This patch protects adjustment, finalization, and initialization-related code
from scenarios where a private type may not have been successfully frozen due
to a missing full view.

------------
-- Source --
------------

--  missing_view.ads

with Ada.Finalization; use Ada.Finalization;

package Missing_View is
   type Ctrl is new Controlled with private;
   type Rec  is new Controlled with private;

private
   type Rec is new Controlled with record
      Comp : Ctrl;
   end record;
end Missing_View;

----------------------------
-- Compilation and output --
----------------------------

$ gcc -c missing_view.ads
missing_view.ads:4:09: missing full declaration for private extension
missing_view.ads:8:09: premature usage of incomplete type "Rec" defined at line 
8

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

2017-01-12  Hristian Kirtchev  <kirtc...@adacore.com>

        * exp_aggr.adb (Build_Record_Aggr_Code): Guard against a missing
        adjustment primitive when the ancestor type was not properly frozen.
        (Gen_Assign): Guard against a missing initialization
        primitive when the component type was not properly frozen.
        (Initialize_Array_Component): Guard against a missing adjustment
        primitive when the component type was not properly frozen.
        (Initialize_Record_Component): Guard against a missing adjustment
        primitive when the component type was not properly frozen.
        (Process_Transient_Component_Completion): The transient object may
        not be finalized when its associated type was not properly frozen.
        * exp_ch3.adb (Build_Assignment): Guard against a missing
        adjustment primitive when the component type was not properly frozen.
        (Build_Initialization_Call): Guard against a missing
        initialization primitive when the associated type was not properly
        frozen.
        (Expand_N_Object_Declaration): Guard against a missing
        adjustment primitive when the base type was not properly frozen.
        (Predefined_Primitive_Bodies): Create an empty Deep_Adjust
        body when there is no adjustment primitive available. Create an
        empty Deep_Finalize body when there is no finalization primitive
        available.
        * exp_ch4.adb (Apply_Accessibility_Check): Guard against a
        missing finalization primitive when the designated type was
        not properly frozen.
        (Expand_N_Allocator): Guard against a missing initialization primitive
        when the designated type was not properly frozen.
        * exp_ch5.adb (Make_Tag_Ctrl_Assignment): Add the adjustment call
        only when the corresponding adjustment primitive is available.
        * exp_ch7.adb (Build_Adjust_Or_Finalize_Statements): Generate the
        adjustment/finalization statements only when there is an available
        primitive to carry out the action.
        (Build_Initialize_Statements): Generate the initialization/finalization
        statements only when there is an available primitive to carry out the
        action.
        (Make_Adjust_Call): Do not generate a call when the underlying
        type is not present due to a possible missing full view.
        (Make_Final_Call): Do not generate a call when the underlying
        type is not present due to a possible missing full view.
        (Make_Finalize_Address_Stmts): Generate an empty body when the
        designated type lacks a finalization primitive.
        (Make_Init_Call): Do not generate a call when the underlying type is
        not present due to a possible missing full view.
        (Process_Component_For_Adjust): Add the adjustment call only when the
        corresponding adjustment primitive is available.
        (Process_Component_For_Finalize): Add the finalization call only when
        the corresponding finalization primitive is available.
        (Process_Object_Declaration): Use a null statement to emulate a
        missing call to the finalization primitive of the object type.
        * exp_ch7.ads (Make_Adjust_Call): Update the comment on usage.
        (Make_Final_Call): Update the comment on usage.
        (Make_Init_Call): Update the comment on usage.
        * exp_util.adb (Build_Transient_Object_Statements): Code reformatting.

Index: exp_aggr.adb
===================================================================
--- exp_aggr.adb        (revision 244350)
+++ exp_aggr.adb        (working copy)
@@ -1128,6 +1128,7 @@
                                   and then Needs_Finalization (Comp_Typ);
 
             Full_Typ  : constant Entity_Id := Underlying_Type (Comp_Typ);
+            Adj_Call  : Node_Id;
             Blk_Stmts : List_Id;
             Init_Stmt : Node_Id;
 
@@ -1222,10 +1223,17 @@
                   and then Is_Controlled (Component_Type (Comp_Typ))
                   and then Nkind (Expr) = N_Aggregate)
             then
-               Append_To (Blk_Stmts,
+               Adj_Call :=
                  Make_Adjust_Call
                    (Obj_Ref => New_Copy_Tree (Arr_Comp),
-                    Typ     => Comp_Typ));
+                    Typ     => Comp_Typ);
+
+               --  Guard against a missing [Deep_]Adjust when the component
+               --  type was not frozen properly.
+
+               if Present (Adj_Call) then
+                  Append_To (Blk_Stmts, Adj_Call);
+               end if;
             end if;
 
             --  Complete the protection of the initialization statements
@@ -1390,6 +1398,7 @@
          Comp_Typ     : Entity_Id := Empty;
          Expr_Q       : Node_Id;
          Indexed_Comp : Node_Id;
+         Init_Call    : Node_Id;
          New_Indexes  : List_Id;
 
       --  Start of processing for Gen_Assign
@@ -1613,10 +1622,17 @@
             end if;
 
             if Needs_Finalization (Ctype) then
-               Append_To (Stmts,
+               Init_Call :=
                  Make_Init_Call
                    (Obj_Ref => New_Copy_Tree (Indexed_Comp),
-                    Typ     => Ctype));
+                    Typ     => Ctype);
+
+               --  Guard against a missing [Deep_]Initialize when the component
+               --  type was not properly frozen.
+
+               if Present (Init_Call) then
+                  Append_To (Stmts, Init_Call);
+               end if;
             end if;
          end if;
 
@@ -2847,6 +2863,7 @@
          Finalization_OK : constant Boolean := Needs_Finalization (Comp_Typ);
 
          Full_Typ  : constant Entity_Id := Underlying_Type (Comp_Typ);
+         Adj_Call  : Node_Id;
          Blk_Stmts : List_Id;
          Init_Stmt : Node_Id;
 
@@ -2912,10 +2929,17 @@
          --    [Deep_]Adjust (Rec_Comp);
 
          if Finalization_OK and then not Is_Limited_Type (Comp_Typ) then
-            Append_To (Blk_Stmts,
+            Adj_Call :=
               Make_Adjust_Call
                 (Obj_Ref => New_Copy_Tree (Rec_Comp),
-                 Typ     => Comp_Typ));
+                 Typ     => Comp_Typ);
+
+            --  Guard against a missing [Deep_]Adjust when the component type
+            --  was not properly frozen.
+
+            if Present (Adj_Call) then
+               Append_To (Blk_Stmts, Adj_Call);
+            end if;
          end if;
 
          --  Complete the protection of the initialization statements
@@ -3062,6 +3086,7 @@
       if Nkind (N) = N_Extension_Aggregate then
          declare
             Ancestor : constant Node_Id := Ancestor_Part (N);
+            Adj_Call : Node_Id;
             Assign   : List_Id;
 
          begin
@@ -3274,10 +3299,17 @@
                if Needs_Finalization (Etype (Ancestor))
                  and then not Is_Limited_Type (Etype (Ancestor))
                then
-                  Append_To (Assign,
+                  Adj_Call :=
                     Make_Adjust_Call
                       (Obj_Ref => New_Copy_Tree (Ref),
-                       Typ     => Etype (Ancestor)));
+                       Typ     => Etype (Ancestor));
+
+                  --  Guard against a missing [Deep_]Adjust when the ancestor
+                  --  type was not properly frozen.
+
+                  if Present (Adj_Call) then
+                     Append_To (Assign, Adj_Call);
+                  end if;
                end if;
 
                Append_To (L,
@@ -7832,7 +7864,6 @@
                         not Restriction_Active (No_Exception_Propagation);
 
    begin
-      pragma Assert (Present (Fin_Call));
       pragma Assert (Present (Hook_Clear));
 
       --  Generate the following code if exception propagation is allowed:
@@ -7872,6 +7903,7 @@
          Abort_And_Exception : declare
             Blk_Decls : constant List_Id := New_List;
             Blk_Stmts : constant List_Id := New_List;
+            Fin_Stmts : constant List_Id := New_List;
 
             Fin_Data : Finalization_Exception_Data;
 
@@ -7892,13 +7924,17 @@
             --  Wrap the hook clear and the finalization call in order to trap
             --  a potential exception.
 
+            Append_To (Fin_Stmts, Hook_Clear);
+
+            if Present (Fin_Call) then
+               Append_To (Fin_Stmts, Fin_Call);
+            end if;
+
             Append_To (Blk_Stmts,
               Make_Block_Statement (Loc,
                 Handled_Statement_Sequence =>
                   Make_Handled_Sequence_Of_Statements (Loc,
-                    Statements         => New_List (
-                      Hook_Clear,
-                      Fin_Call),
+                    Statements         => Fin_Stmts,
                     Exception_Handlers => New_List (
                       Build_Exception_Handler (Fin_Data)))));
 
@@ -7943,8 +7979,11 @@
          begin
             Append_To (Blk_Stmts, Build_Runtime_Call (Loc, RE_Abort_Defer));
             Append_To (Blk_Stmts, Hook_Clear);
-            Append_To (Blk_Stmts, Fin_Call);
 
+            if Present (Fin_Call) then
+               Append_To (Blk_Stmts, Fin_Call);
+            end if;
+
             Append_To (Stmts,
               Build_Abort_Undefer_Block (Loc,
                 Stmts   => Blk_Stmts,
@@ -7958,7 +7997,10 @@
 
       else
          Append_To (Stmts, Hook_Clear);
-         Append_To (Stmts, Fin_Call);
+
+         if Present (Fin_Call) then
+            Append_To (Stmts, Fin_Call);
+         end if;
       end if;
    end Process_Transient_Component_Completion;
 
Index: exp_ch3.adb
===================================================================
--- exp_ch3.adb (revision 244360)
+++ exp_ch3.adb (working copy)
@@ -1295,6 +1295,7 @@
       First_Arg      : Node_Id;
       Full_Init_Type : Entity_Id;
       Full_Type      : Entity_Id;
+      Init_Call      : Node_Id;
       Init_Type      : Entity_Id;
       Proc           : Entity_Id;
 
@@ -1515,7 +1516,7 @@
             then
                Append_To (Args,
                  Make_Selected_Component (Loc,
-                   Prefix => New_Copy_Tree (Prefix (Id_Ref)),
+                   Prefix        => New_Copy_Tree (Prefix (Id_Ref)),
                    Selector_Name => Arg));
             else
                Append_To (Args, Arg);
@@ -1542,17 +1543,24 @@
 
       Append_To (Res,
         Make_Procedure_Call_Statement (Loc,
-          Name => New_Occurrence_Of (Proc, Loc),
+          Name                   => New_Occurrence_Of (Proc, Loc),
           Parameter_Associations => Args));
 
       if Needs_Finalization (Typ)
         and then Nkind (Id_Ref) = N_Selected_Component
       then
          if Chars (Selector_Name (Id_Ref)) /= Name_uParent then
-            Append_To (Res,
+            Init_Call :=
               Make_Init_Call
                 (Obj_Ref => New_Copy_Tree (First_Arg),
-                 Typ     => Typ));
+                 Typ     => Typ);
+
+            --  Guard against a missing [Deep_]Initialize when the type was not
+            --  properly frozen.
+
+            if Present (Init_Call) then
+               Append_To (Res, Init_Call);
+            end if;
          end if;
       end if;
 
@@ -1651,11 +1659,13 @@
       function Build_Assignment (Id : Entity_Id; N : Node_Id) return List_Id is
          N_Loc : constant Source_Ptr := Sloc (N);
          Typ   : constant Entity_Id := Underlying_Type (Etype (Id));
-         Exp   : Node_Id := N;
-         Kind  : Node_Kind := Nkind (N);
-         Lhs   : Node_Id;
-         Res   : List_Id;
 
+         Adj_Call : Node_Id;
+         Exp      : Node_Id   := N;
+         Kind     : Node_Kind := Nkind (N);
+         Lhs      : Node_Id;
+         Res      : List_Id;
+
       begin
          Lhs :=
            Make_Selected_Component (N_Loc,
@@ -1734,10 +1744,17 @@
            and then not (Nkind_In (Kind, N_Aggregate, N_Extension_Aggregate))
            and then not Is_Limited_View (Typ)
          then
-            Append_To (Res,
+            Adj_Call :=
               Make_Adjust_Call
                 (Obj_Ref => New_Copy_Tree (Lhs),
-                 Typ     => Etype (Id)));
+                 Typ     => Etype (Id));
+
+            --  Guard against a missing [Deep_]Adjust when the component type
+            --  was not properly frozen.
+
+            if Present (Adj_Call) then
+               Append_To (Res, Adj_Call);
+            end if;
          end if;
 
          --  If a component type has a predicate, add check to the component
@@ -5830,7 +5847,9 @@
 
       --  Local variables
 
-      Next_N     : constant Node_Id := Next (N);
+      Next_N : constant Node_Id := Next (N);
+
+      Adj_Call   : Node_Id;
       Id_Ref     : Node_Id;
       Tag_Assign : Node_Id;
 
@@ -6332,10 +6351,17 @@
               and then not Is_Limited_View (Typ)
               and then not Rewrite_As_Renaming
             then
-               Insert_Action_After (Init_After,
+               Adj_Call :=
                  Make_Adjust_Call (
                    Obj_Ref => New_Occurrence_Of (Def_Id, Loc),
-                   Typ     => Base_Typ));
+                   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
@@ -9530,7 +9556,9 @@
    is
       Loc       : constant Source_Ptr := Sloc (Tag_Typ);
       Res       : constant List_Id    := New_List;
+      Adj_Call  : Node_Id;
       Decl      : Node_Id;
+      Fin_Call  : Node_Id;
       Prim      : Elmt_Id;
       Eq_Needed : Boolean;
       Eq_Name   : Name_Id;
@@ -9756,42 +9784,45 @@
 
       elsif not Has_Controlled_Component (Tag_Typ) then
          if not Is_Limited_Type (Tag_Typ) then
-            Decl := Predef_Deep_Spec (Loc, Tag_Typ, TSS_Deep_Adjust, True);
+            Adj_Call := Empty;
+            Decl     := Predef_Deep_Spec (Loc, Tag_Typ, TSS_Deep_Adjust, True);
 
             if Is_Controlled (Tag_Typ) then
-               Set_Handled_Statement_Sequence (Decl,
-                 Make_Handled_Sequence_Of_Statements (Loc,
-                   Statements => New_List (
-                     Make_Adjust_Call (
-                       Obj_Ref => Make_Identifier (Loc, Name_V),
-                       Typ     => Tag_Typ))));
+               Adj_Call :=
+                 Make_Adjust_Call (
+                   Obj_Ref => Make_Identifier (Loc, Name_V),
+                   Typ     => Tag_Typ);
+            end if;
 
-            else
-               Set_Handled_Statement_Sequence (Decl,
-                 Make_Handled_Sequence_Of_Statements (Loc,
-                   Statements => New_List (
-                     Make_Null_Statement (Loc))));
+            if No (Adj_Call) then
+               Adj_Call := Make_Null_Statement (Loc);
             end if;
 
+            Set_Handled_Statement_Sequence (Decl,
+              Make_Handled_Sequence_Of_Statements (Loc,
+                Statements => New_List (Adj_Call)));
+
             Append_To (Res, Decl);
          end if;
 
-         Decl := Predef_Deep_Spec (Loc, Tag_Typ, TSS_Deep_Finalize, True);
+         Fin_Call := Empty;
+         Decl     := Predef_Deep_Spec (Loc, Tag_Typ, TSS_Deep_Finalize, True);
 
          if Is_Controlled (Tag_Typ) then
-            Set_Handled_Statement_Sequence (Decl,
-              Make_Handled_Sequence_Of_Statements (Loc,
-                Statements => New_List (
-                  Make_Final_Call
-                    (Obj_Ref => Make_Identifier (Loc, Name_V),
-                     Typ     => Tag_Typ))));
+            Fin_Call :=
+              Make_Final_Call
+                (Obj_Ref => Make_Identifier (Loc, Name_V),
+                 Typ     => Tag_Typ);
+         end if;
 
-         else
-            Set_Handled_Statement_Sequence (Decl,
-              Make_Handled_Sequence_Of_Statements (Loc,
-                Statements => New_List (Make_Null_Statement (Loc))));
+         if No (Fin_Call) then
+            Fin_Call := Make_Null_Statement (Loc);
          end if;
 
+         Set_Handled_Statement_Sequence (Decl,
+           Make_Handled_Sequence_Of_Statements (Loc,
+             Statements => New_List (Fin_Call)));
+
          Append_To (Res, Decl);
       end if;
 
Index: exp_ch4.adb
===================================================================
--- exp_ch4.adb (revision 244350)
+++ exp_ch4.adb (working copy)
@@ -632,6 +632,13 @@
                       Make_Explicit_Dereference (Loc, New_Copy (Obj_Ref)),
                     Typ     => DesigT);
 
+               --  Guard against a missing [Deep_]Finalize when the designated
+               --  type was not properly frozen.
+
+               if No (Fin_Call) then
+                  Fin_Call := Make_Null_Statement (Loc);
+               end if;
+
                --  When the target or profile supports deallocation, wrap the
                --  finalization call in a block to ensure proper deallocation
                --  even if finalization fails. Generate:
@@ -722,6 +729,7 @@
       Aggr_In_Place : constant Boolean   := Is_Delayed_Aggregate (Exp);
       Indic         : constant Node_Id   := Subtype_Mark (Expression (N));
       T             : constant Entity_Id := Entity (Indic);
+      Adj_Call      : Node_Id;
       Node          : Node_Id;
       Tag_Assign    : Node_Id;
       Temp          : Entity_Id;
@@ -1060,13 +1068,17 @@
             --  the designated type can be an ancestor of the subtype mark of
             --  the allocator.
 
-            Insert_Action (N,
+            Adj_Call :=
               Make_Adjust_Call
                 (Obj_Ref =>
                    Unchecked_Convert_To (T,
                      Make_Explicit_Dereference (Loc,
                        Prefix => New_Occurrence_Of (Temp, Loc))),
-                 Typ     => T));
+                 Typ     => T);
+
+            if Present (Adj_Call) then
+               Insert_Action (N, Adj_Call);
+            end if;
          end if;
 
          --  Note: the accessibility check must be inserted after the call to
@@ -4315,6 +4327,7 @@
          Discr     : Elmt_Id;
          Init      : Entity_Id;
          Init_Arg1 : Node_Id;
+         Init_Call : Node_Id;
          Temp_Decl : Node_Id;
          Temp_Type : Entity_Id;
 
@@ -4635,10 +4648,17 @@
                   --  Generate:
                   --    [Deep_]Initialize (Init_Arg1);
 
-                  Insert_Action (N,
+                  Init_Call :=
                     Make_Init_Call
                       (Obj_Ref => New_Copy_Tree (Init_Arg1),
-                       Typ     => T));
+                       Typ     => T);
+
+                  --  Guard against a missing [Deep_]Initialize when the
+                  --  designated type was not properly frozen.
+
+                  if Present (Init_Call) then
+                     Insert_Action (N, Init_Call);
+                  end if;
                end if;
 
                Rewrite (N, New_Occurrence_Of (Temp, Loc));
Index: exp_ch5.adb
===================================================================
--- exp_ch5.adb (revision 244356)
+++ exp_ch5.adb (working copy)
@@ -4676,7 +4676,9 @@
                                        and then not Comp_Asn
                                        and then not No_Ctrl_Actions (N)
                                        and then Tagged_Type_Expansion;
-      Tag_Id  : Entity_Id;
+      Adj_Call : Node_Id;
+      Fin_Call : Node_Id;
+      Tag_Id   : Entity_Id;
 
    begin
       --  Finalize the target of the assignment when controlled
@@ -4709,10 +4711,14 @@
          null;
 
       else
-         Append_To (Res,
+         Fin_Call :=
            Make_Final_Call
              (Obj_Ref => Duplicate_Subexpr_No_Checks (L),
-              Typ     => Etype (L)));
+              Typ     => Etype (L));
+
+         if Present (Fin_Call) then
+            Append_To (Res, Fin_Call);
+         end if;
       end if;
 
       --  Save the Tag in a local variable Tag_Id
@@ -4765,10 +4771,14 @@
       --  init proc since it is an initialization more than an assignment).
 
       if Ctrl_Act then
-         Append_To (Res,
+         Adj_Call :=
            Make_Adjust_Call
              (Obj_Ref => Duplicate_Subexpr_Move_Checks (L),
-              Typ     => Etype (L)));
+              Typ     => Etype (L));
+
+         if Present (Adj_Call) then
+            Append_To (Res, Adj_Call);
+         end if;
       end if;
 
       return Res;
Index: exp_ch7.adb
===================================================================
--- exp_ch7.adb (revision 244352)
+++ exp_ch7.adb (working copy)
@@ -3062,6 +3062,13 @@
                 Obj_Ref => Obj_Ref,
                 Typ     => Obj_Typ);
 
+            --  Guard against a missing [Deep_]Finalize when the object type
+            --  was not properly frozen.
+
+            if No (Fin_Call) then
+               Fin_Call := Make_Null_Statement (Loc);
+            end if;
+
             --  For CodePeer, the exception handlers normally generated here
             --  generate complex flowgraphs which result in capacity problems.
             --  Omitting these handlers for CodePeer is justified as follows:
@@ -6905,10 +6912,12 @@
    is
       Loc    : constant Source_Ptr := Sloc (Obj_Ref);
       Adj_Id : Entity_Id := Empty;
-      Ref    : Node_Id   := Obj_Ref;
+      Ref    : Node_Id;
       Utyp   : Entity_Id;
 
    begin
+      Ref := Obj_Ref;
+
       --  Recover the proper type which contains Deep_Adjust
 
       if Is_Class_Wide_Type (Typ) then
@@ -6922,7 +6931,7 @@
 
       --  Deal with untagged derivation of private views
 
-      if Is_Untagged_Derivation (Typ) then
+      if Present (Utyp) and then Is_Untagged_Derivation (Typ) then
          Utyp := Underlying_Type (Root_Type (Base_Type (Typ)));
          Ref  := Unchecked_Convert_To (Utyp, Ref);
          Set_Assignment_OK (Ref);
@@ -6931,14 +6940,21 @@
       --  When dealing with the completion of a private type, use the base
       --  type instead.
 
-      if Utyp /= Base_Type (Utyp) then
+      if Present (Utyp) and then Utyp /= Base_Type (Utyp) then
          pragma Assert (Is_Private_Type (Typ));
 
          Utyp := Base_Type (Utyp);
          Ref  := Unchecked_Convert_To (Utyp, Ref);
       end if;
 
-      if Skip_Self then
+      --  The underlying type may not be present due to a missing full view. In
+      --  this case freezing did not take place and there is no [Deep_]Adjust
+      --  primitive to call.
+
+      if No (Utyp) then
+         return Empty;
+
+      elsif Skip_Self then
          if Has_Controlled_Component (Utyp) then
             if Is_Tagged_Type (Utyp) then
                Adj_Id := Find_Optional_Prim_Op (Utyp, TSS_Deep_Adjust);
@@ -6998,7 +7014,7 @@
          return
            Make_Call (Loc,
              Proc_Id   => Adj_Id,
-             Param     => New_Copy_Tree (Ref),
+             Param     => Ref,
              Skip_Self => Skip_Self);
       else
          return Empty;
@@ -7171,23 +7187,13 @@
       function Build_Adjust_Or_Finalize_Statements
         (Typ : Entity_Id) return List_Id
       is
-         Comp_Typ       : constant Entity_Id  := Component_Type (Typ);
-         Exceptions_OK  : constant Boolean    :=
-                            not Restriction_Active (No_Exception_Propagation);
-         Index_List     : constant List_Id    := New_List;
-         Loc            : constant Source_Ptr := Sloc (Typ);
-         Num_Dims       : constant Int        := Number_Dimensions (Typ);
+         Comp_Typ      : constant Entity_Id  := Component_Type (Typ);
+         Exceptions_OK : constant Boolean    :=
+                           not Restriction_Active (No_Exception_Propagation);
+         Index_List    : constant List_Id    := New_List;
+         Loc           : constant Source_Ptr := Sloc (Typ);
+         Num_Dims      : constant Int        := Number_Dimensions (Typ);
 
-         Finalizer_Decls : List_Id := No_List;
-         Finalizer_Data  : Finalization_Exception_Data;
-         Call            : Node_Id;
-         Comp_Ref        : Node_Id;
-         Core_Loop       : Node_Id;
-         Dim             : Int;
-         J               : Entity_Id;
-         Loop_Id         : Entity_Id;
-         Stmts           : List_Id;
-
          procedure Build_Indexes;
          --  Generate the indexes used in the dimension loops
 
@@ -7206,13 +7212,26 @@
             end loop;
          end Build_Indexes;
 
+         --  Local variables
+
+         Final_Decls : List_Id := No_List;
+         Final_Data  : Finalization_Exception_Data;
+         Block       : Node_Id;
+         Call        : Node_Id;
+         Comp_Ref    : Node_Id;
+         Core_Loop   : Node_Id;
+         Dim         : Int;
+         J           : Entity_Id;
+         Loop_Id     : Entity_Id;
+         Stmts       : List_Id;
+
       --  Start of processing for Build_Adjust_Or_Finalize_Statements
 
       begin
-         Finalizer_Decls := New_List;
+         Final_Decls := New_List;
 
          Build_Indexes;
-         Build_Object_Declarations (Finalizer_Data, Finalizer_Decls, Loc);
+         Build_Object_Declarations (Final_Data, Final_Decls, Loc);
 
          Comp_Ref :=
            Make_Indexed_Component (Loc,
@@ -7233,99 +7252,111 @@
             Call := Make_Final_Call (Obj_Ref => Comp_Ref, Typ => Comp_Typ);
          end if;
 
-         --  Generate the block which houses the adjust or finalize call:
+         if Present (Call) then
 
-         --    begin
-         --       <adjust or finalize call>
+            --  Generate the block which houses the adjust or finalize call:
 
-         --    exception
-         --       when others =>
-         --          if not Raised then
-         --             Raised := True;
-         --             Save_Occurrence (E, Get_Current_Excep.all.all);
-         --          end if;
-         --    end;
+            --    begin
+            --       <adjust or finalize call>
 
-         if Exceptions_OK then
-            Core_Loop :=
-              Make_Block_Statement (Loc,
-                Handled_Statement_Sequence =>
-                  Make_Handled_Sequence_Of_Statements (Loc,
-                    Statements         => New_List (Call),
-                    Exception_Handlers => New_List (
-                      Build_Exception_Handler (Finalizer_Data))));
-         else
-            Core_Loop := Call;
-         end if;
+            --    exception
+            --       when others =>
+            --          if not Raised then
+            --             Raised := True;
+            --             Save_Occurrence (E, Get_Current_Excep.all.all);
+            --          end if;
+            --    end;
 
-         --  Generate the dimension loops starting from the innermost one
+            if Exceptions_OK then
+               Core_Loop :=
+                 Make_Block_Statement (Loc,
+                   Handled_Statement_Sequence =>
+                     Make_Handled_Sequence_Of_Statements (Loc,
+                       Statements         => New_List (Call),
+                       Exception_Handlers => New_List (
+                         Build_Exception_Handler (Final_Data))));
+            else
+               Core_Loop := Call;
+            end if;
 
-         --    for Jnn in [reverse] V'Range (Dim) loop
-         --       <core loop>
-         --    end loop;
+            --  Generate the dimension loops starting from the innermost one
 
-         J := Last (Index_List);
-         Dim := Num_Dims;
-         while Present (J) and then Dim > 0 loop
-            Loop_Id := J;
-            Prev (J);
-            Remove (Loop_Id);
+            --    for Jnn in [reverse] V'Range (Dim) loop
+            --       <core loop>
+            --    end loop;
 
-            Core_Loop :=
-              Make_Loop_Statement (Loc,
-                Iteration_Scheme =>
-                  Make_Iteration_Scheme (Loc,
-                    Loop_Parameter_Specification =>
-                      Make_Loop_Parameter_Specification (Loc,
-                        Defining_Identifier         => Loop_Id,
-                        Discrete_Subtype_Definition =>
-                          Make_Attribute_Reference (Loc,
-                            Prefix         => Make_Identifier (Loc, Name_V),
-                            Attribute_Name => Name_Range,
-                            Expressions    => New_List (
-                              Make_Integer_Literal (Loc, Dim))),
+            J := Last (Index_List);
+            Dim := Num_Dims;
+            while Present (J) and then Dim > 0 loop
+               Loop_Id := J;
+               Prev (J);
+               Remove (Loop_Id);
 
-                        Reverse_Present => Prim = Finalize_Case)),
+               Core_Loop :=
+                 Make_Loop_Statement (Loc,
+                   Iteration_Scheme =>
+                     Make_Iteration_Scheme (Loc,
+                       Loop_Parameter_Specification =>
+                         Make_Loop_Parameter_Specification (Loc,
+                           Defining_Identifier         => Loop_Id,
+                           Discrete_Subtype_Definition =>
+                             Make_Attribute_Reference (Loc,
+                               Prefix         => Make_Identifier (Loc, Name_V),
+                               Attribute_Name => Name_Range,
+                               Expressions    => New_List (
+                                 Make_Integer_Literal (Loc, Dim))),
 
-                Statements => New_List (Core_Loop),
-                End_Label  => Empty);
+                           Reverse_Present             =>
+                             Prim = Finalize_Case)),
 
-            Dim := Dim - 1;
-         end loop;
+                   Statements       => New_List (Core_Loop),
+                   End_Label        => Empty);
 
-         --  Generate the block which contains the core loop, the declarations
-         --  of the abort flag, the exception occurrence, the raised flag and
-         --  the conditional raise:
+               Dim := Dim - 1;
+            end loop;
 
-         --    declare
-         --       Abort  : constant Boolean := Triggered_By_Abort;
-         --         <or>
-         --       Abort  : constant Boolean := False;  --  no abort
+            --  Generate the block which contains the core loop, declarations
+            --  of the abort flag, the exception occurrence, the raised flag
+            --  and the conditional raise:
 
-         --       E      : Exception_Occurrence;
-         --       Raised : Boolean := False;
+            --    declare
+            --       Abort  : constant Boolean := Triggered_By_Abort;
+            --         <or>
+            --       Abort  : constant Boolean := False;  --  no abort
 
-         --    begin
-         --       <core loop>
+            --       E      : Exception_Occurrence;
+            --       Raised : Boolean := False;
 
-         --       if Raised and then not Abort then
-         --          Raise_From_Controlled_Operation (E);
-         --       end if;
-         --    end;
+            --    begin
+            --       <core loop>
 
-         Stmts := New_List (Core_Loop);
+            --       if Raised and then not Abort then
+            --          Raise_From_Controlled_Operation (E);
+            --       end if;
+            --    end;
 
-         if Exceptions_OK then
-            Append_To (Stmts, Build_Raise_Statement (Finalizer_Data));
+            Stmts := New_List (Core_Loop);
+
+            if Exceptions_OK then
+               Append_To (Stmts, Build_Raise_Statement (Final_Data));
+            end if;
+
+            Block :=
+              Make_Block_Statement (Loc,
+                Declarations               => Final_Decls,
+                Handled_Statement_Sequence =>
+                  Make_Handled_Sequence_Of_Statements (Loc,
+                    Statements => Stmts));
+
+         --  Otherwise previous errors or a missing full view may prevent the
+         --  proper freezing of the component type. If this is the case, there
+         --  is no [Deep_]Adjust or [Deep_]Finalize primitive to call.
+
+         else
+            Block := Make_Null_Statement (Loc);
          end if;
 
-         return
-           New_List (
-             Make_Block_Statement (Loc,
-               Declarations               =>
-                 Finalizer_Decls,
-               Handled_Statement_Sequence =>
-                 Make_Handled_Sequence_Of_Statements (Loc, Stmts)));
+         return New_List (Block);
       end Build_Adjust_Or_Finalize_Statements;
 
       ---------------------------------
@@ -7333,32 +7364,21 @@
       ---------------------------------
 
       function Build_Initialize_Statements (Typ : Entity_Id) return List_Id is
-         Comp_Typ       : constant Entity_Id  := Component_Type (Typ);
-         Exceptions_OK  : constant Boolean    :=
-                            not Restriction_Active (No_Exception_Propagation);
-         Final_List     : constant List_Id    := New_List;
-         Index_List     : constant List_Id    := New_List;
-         Loc            : constant Source_Ptr := Sloc (Typ);
-         Num_Dims       : constant Int        := Number_Dimensions (Typ);
+         Comp_Typ      : constant Entity_Id  := Component_Type (Typ);
+         Exceptions_OK : constant Boolean    :=
+                           not Restriction_Active (No_Exception_Propagation);
+         Final_List    : constant List_Id    := New_List;
+         Index_List    : constant List_Id    := New_List;
+         Loc           : constant Source_Ptr := Sloc (Typ);
+         Num_Dims      : constant Int        := Number_Dimensions (Typ);
 
-         Counter_Id      : Entity_Id;
-         Dim             : Int;
-         F               : Node_Id;
-         Fin_Stmt        : Node_Id;
-         Final_Block     : Node_Id;
-         Final_Loop      : Node_Id;
-         Finalizer_Data  : Finalization_Exception_Data;
-         Finalizer_Decls : List_Id := No_List;
-         Init_Loop       : Node_Id;
-         J               : Node_Id;
-         Loop_Id         : Node_Id;
-         Stmts           : List_Id;
-
-         function Build_Counter_Assignment return Node_Id;
+         function Build_Assignment (Counter_Id : Entity_Id) return Node_Id;
          --  Generate the following assignment:
          --    Counter := V'Length (1) *
          --               ...
          --               V'Length (N) - Counter;
+         --
+         --  Counter_Id denotes the entity of the counter.
 
          function Build_Finalization_Call return Node_Id;
          --  Generate a deep finalization call for an array element
@@ -7370,11 +7390,11 @@
          function Build_Initialization_Call return Node_Id;
          --  Generate a deep initialization call for an array element
 
-         ------------------------------
-         -- Build_Counter_Assignment --
-         ------------------------------
+         ----------------------
+         -- Build_Assignment --
+         ----------------------
 
-         function Build_Counter_Assignment return Node_Id is
+         function Build_Assignment (Counter_Id : Entity_Id) return Node_Id is
             Dim  : Int;
             Expr : Node_Id;
 
@@ -7417,7 +7437,7 @@
                   Make_Op_Subtract (Loc,
                     Left_Opnd  => Expr,
                     Right_Opnd => New_Occurrence_Of (Counter_Id, Loc)));
-         end Build_Counter_Assignment;
+         end Build_Assignment;
 
          -----------------------------
          -- Build_Finalization_Call --
@@ -7476,14 +7496,31 @@
             return Make_Init_Call (Obj_Ref => Comp_Ref, Typ => Comp_Typ);
          end Build_Initialization_Call;
 
+         --  Local variables
+
+         Counter_Id  : Entity_Id;
+         Dim         : Int;
+         F           : Node_Id;
+         Fin_Stmt    : Node_Id;
+         Final_Block : Node_Id;
+         Final_Data  : Finalization_Exception_Data;
+         Final_Decls : List_Id := No_List;
+         Final_Loop  : Node_Id;
+         Init_Block  : Node_Id;
+         Init_Call   : Node_Id;
+         Init_Loop   : Node_Id;
+         J           : Node_Id;
+         Loop_Id     : Node_Id;
+         Stmts       : List_Id;
+
       --  Start of processing for Build_Initialize_Statements
 
       begin
-         Counter_Id := Make_Temporary (Loc, 'C');
-         Finalizer_Decls := New_List;
+         Counter_Id  := Make_Temporary (Loc, 'C');
+         Final_Decls := New_List;
 
          Build_Indexes;
-         Build_Object_Declarations (Finalizer_Data, Finalizer_Decls, Loc);
+         Build_Object_Declarations (Final_Data, Final_Decls, Loc);
 
          --  Generate the block which houses the finalization call, the index
          --  guard and the handler which triggers Program_Error later on.
@@ -7502,115 +7539,124 @@
          --       end;
          --    end if;
 
-         if Exceptions_OK then
-            Fin_Stmt :=
-              Make_Block_Statement (Loc,
-                Handled_Statement_Sequence =>
-                  Make_Handled_Sequence_Of_Statements (Loc,
-                    Statements         => New_List (Build_Finalization_Call),
-                    Exception_Handlers => New_List (
-                      Build_Exception_Handler (Finalizer_Data))));
-         else
-            Fin_Stmt := Build_Finalization_Call;
-         end if;
+         Fin_Stmt := Build_Finalization_Call;
 
-         --  This is the core of the loop, the dimension iterators are added
-         --  one by one in reverse.
+         if Present (Fin_Stmt) then
+            if Exceptions_OK then
+               Fin_Stmt :=
+                 Make_Block_Statement (Loc,
+                   Handled_Statement_Sequence =>
+                     Make_Handled_Sequence_Of_Statements (Loc,
+                       Statements         => New_List (Fin_Stmt),
+                       Exception_Handlers => New_List (
+                         Build_Exception_Handler (Final_Data))));
+            end if;
 
-         Final_Loop :=
-           Make_If_Statement (Loc,
-             Condition =>
-               Make_Op_Gt (Loc,
-                 Left_Opnd  => New_Occurrence_Of (Counter_Id, Loc),
-                 Right_Opnd => Make_Integer_Literal (Loc, 0)),
+            --  This is the core of the loop, the dimension iterators are added
+            --  one by one in reverse.
 
-             Then_Statements => New_List (
-               Make_Assignment_Statement (Loc,
-                 Name       => New_Occurrence_Of (Counter_Id, Loc),
-                 Expression =>
-                   Make_Op_Subtract (Loc,
-                     Left_Opnd  => New_Occurrence_Of (Counter_Id, Loc),
-                     Right_Opnd => Make_Integer_Literal (Loc, 1)))),
+            Final_Loop :=
+              Make_If_Statement (Loc,
+                Condition =>
+                  Make_Op_Gt (Loc,
+                    Left_Opnd  => New_Occurrence_Of (Counter_Id, Loc),
+                    Right_Opnd => Make_Integer_Literal (Loc, 0)),
 
-             Else_Statements => New_List (Fin_Stmt));
+                Then_Statements => New_List (
+                  Make_Assignment_Statement (Loc,
+                    Name       => New_Occurrence_Of (Counter_Id, Loc),
+                    Expression =>
+                      Make_Op_Subtract (Loc,
+                        Left_Opnd  => New_Occurrence_Of (Counter_Id, Loc),
+                        Right_Opnd => Make_Integer_Literal (Loc, 1)))),
 
-         --  Generate all finalization loops starting from the innermost
-         --  dimension.
+                Else_Statements => New_List (Fin_Stmt));
 
-         --    for Fnn in reverse V'Range (Dim) loop
-         --       <final loop>
-         --    end loop;
+            --  Generate all finalization loops starting from the innermost
+            --  dimension.
 
-         F := Last (Final_List);
-         Dim := Num_Dims;
-         while Present (F) and then Dim > 0 loop
-            Loop_Id := F;
-            Prev (F);
-            Remove (Loop_Id);
+            --    for Fnn in reverse V'Range (Dim) loop
+            --       <final loop>
+            --    end loop;
 
-            Final_Loop :=
-              Make_Loop_Statement (Loc,
-                Iteration_Scheme =>
-                  Make_Iteration_Scheme (Loc,
-                    Loop_Parameter_Specification =>
-                      Make_Loop_Parameter_Specification (Loc,
-                        Defining_Identifier => Loop_Id,
-                        Discrete_Subtype_Definition =>
-                          Make_Attribute_Reference (Loc,
-                            Prefix         => Make_Identifier (Loc, Name_V),
-                            Attribute_Name => Name_Range,
-                            Expressions    => New_List (
-                              Make_Integer_Literal (Loc, Dim))),
+            F := Last (Final_List);
+            Dim := Num_Dims;
+            while Present (F) and then Dim > 0 loop
+               Loop_Id := F;
+               Prev (F);
+               Remove (Loop_Id);
 
-                        Reverse_Present => True)),
+               Final_Loop :=
+                 Make_Loop_Statement (Loc,
+                   Iteration_Scheme =>
+                     Make_Iteration_Scheme (Loc,
+                       Loop_Parameter_Specification =>
+                         Make_Loop_Parameter_Specification (Loc,
+                           Defining_Identifier         => Loop_Id,
+                           Discrete_Subtype_Definition =>
+                             Make_Attribute_Reference (Loc,
+                               Prefix         => Make_Identifier (Loc, Name_V),
+                               Attribute_Name => Name_Range,
+                               Expressions    => New_List (
+                                 Make_Integer_Literal (Loc, Dim))),
 
-                Statements => New_List (Final_Loop),
-                End_Label => Empty);
+                           Reverse_Present             => True)),
 
-            Dim := Dim - 1;
-         end loop;
+                   Statements       => New_List (Final_Loop),
+                   End_Label        => Empty);
 
-         --  Generate the block which contains the finalization loops, the
-         --  declarations of the abort flag, the exception occurrence, the
-         --  raised flag and the conditional raise.
+               Dim := Dim - 1;
+            end loop;
 
-         --    declare
-         --       Abort  : constant Boolean := Triggered_By_Abort;
-         --         <or>
-         --       Abort  : constant Boolean := False;  --  no abort
+            --  Generate the block which contains the finalization loops, the
+            --  declarations of the abort flag, the exception occurrence, the
+            --  raised flag and the conditional raise.
 
-         --       E      : Exception_Occurrence;
-         --       Raised : Boolean := False;
+            --    declare
+            --       Abort  : constant Boolean := Triggered_By_Abort;
+            --         <or>
+            --       Abort  : constant Boolean := False;  --  no abort
 
-         --    begin
-         --       Counter :=
-         --         V'Length (1) *
-         --         ...
-         --         V'Length (N) - Counter;
+            --       E      : Exception_Occurrence;
+            --       Raised : Boolean := False;
 
-         --       <final loop>
+            --    begin
+            --       Counter :=
+            --         V'Length (1) *
+            --         ...
+            --         V'Length (N) - Counter;
 
-         --       if Raised and then not Abort then
-         --          Raise_From_Controlled_Operation (E);
-         --       end if;
+            --       <final loop>
 
-         --       raise;
-         --    end;
+            --       if Raised and then not Abort then
+            --          Raise_From_Controlled_Operation (E);
+            --       end if;
 
-         Stmts := New_List (Build_Counter_Assignment, Final_Loop);
+            --       raise;
+            --    end;
 
-         if Exceptions_OK then
-            Append_To (Stmts, Build_Raise_Statement (Finalizer_Data));
-            Append_To (Stmts, Make_Raise_Statement (Loc));
+            Stmts := New_List (Build_Assignment (Counter_Id), Final_Loop);
+
+            if Exceptions_OK then
+               Append_To (Stmts, Build_Raise_Statement (Final_Data));
+               Append_To (Stmts, Make_Raise_Statement (Loc));
+            end if;
+
+            Final_Block :=
+              Make_Block_Statement (Loc,
+                Declarations               => Final_Decls,
+                Handled_Statement_Sequence =>
+                  Make_Handled_Sequence_Of_Statements (Loc,
+                    Statements => Stmts));
+
+         --  Otherwise previous errors or a missing full view may prevent the
+         --  proper freezing of the component type. If this is the case, there
+         --  is no [Deep_]Finalize primitive to call.
+
+         else
+            Final_Block := Make_Null_Statement (Loc);
          end if;
 
-         Final_Block :=
-           Make_Block_Statement (Loc,
-             Declarations               =>
-               Finalizer_Decls,
-             Handled_Statement_Sequence =>
-               Make_Handled_Sequence_Of_Statements (Loc, Statements => Stmts));
-
          --  Generate the block which contains the initialization call and
          --  the partial finalization code.
 
@@ -7624,70 +7670,73 @@
          --          <finalization code>
          --    end;
 
-         Init_Loop :=
-           Make_Block_Statement (Loc,
-             Handled_Statement_Sequence =>
-               Make_Handled_Sequence_Of_Statements (Loc,
-                 Statements         => New_List (Build_Initialization_Call),
-                 Exception_Handlers => New_List (
-                   Make_Exception_Handler (Loc,
-                     Exception_Choices => New_List (Make_Others_Choice (Loc)),
-                     Statements        => New_List (Final_Block)))));
+         Init_Call := Build_Initialization_Call;
 
-         Append_To (Statements (Handled_Statement_Sequence (Init_Loop)),
-           Make_Assignment_Statement (Loc,
-             Name       => New_Occurrence_Of (Counter_Id, Loc),
-             Expression =>
-               Make_Op_Add (Loc,
-                 Left_Opnd  => New_Occurrence_Of (Counter_Id, Loc),
-                 Right_Opnd => Make_Integer_Literal (Loc, 1))));
+         if Present (Init_Call) 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)))));
 
-         --  Generate all initialization loops starting from the innermost
-         --  dimension.
+            Append_To (Statements (Handled_Statement_Sequence (Init_Loop)),
+              Make_Assignment_Statement (Loc,
+                Name       => New_Occurrence_Of (Counter_Id, Loc),
+                Expression =>
+                  Make_Op_Add (Loc,
+                    Left_Opnd  => New_Occurrence_Of (Counter_Id, Loc),
+                    Right_Opnd => Make_Integer_Literal (Loc, 1))));
 
-         --    for Jnn in V'Range (Dim) loop
-         --       <init loop>
-         --    end loop;
+            --  Generate all initialization loops starting from the innermost
+            --  dimension.
 
-         J := Last (Index_List);
-         Dim := Num_Dims;
-         while Present (J) and then Dim > 0 loop
-            Loop_Id := J;
-            Prev (J);
-            Remove (Loop_Id);
+            --    for Jnn in V'Range (Dim) loop
+            --       <init loop>
+            --    end loop;
 
-            Init_Loop :=
-              Make_Loop_Statement (Loc,
-                Iteration_Scheme =>
-                  Make_Iteration_Scheme (Loc,
-                    Loop_Parameter_Specification =>
-                      Make_Loop_Parameter_Specification (Loc,
-                        Defining_Identifier => Loop_Id,
-                        Discrete_Subtype_Definition =>
-                          Make_Attribute_Reference (Loc,
-                            Prefix         => Make_Identifier (Loc, Name_V),
-                            Attribute_Name => Name_Range,
-                            Expressions    => New_List (
-                              Make_Integer_Literal (Loc, Dim))))),
+            J := Last (Index_List);
+            Dim := Num_Dims;
+            while Present (J) and then Dim > 0 loop
+               Loop_Id := J;
+               Prev (J);
+               Remove (Loop_Id);
 
-                Statements => New_List (Init_Loop),
-                End_Label => Empty);
+               Init_Loop :=
+                 Make_Loop_Statement (Loc,
+                   Iteration_Scheme =>
+                     Make_Iteration_Scheme (Loc,
+                       Loop_Parameter_Specification =>
+                         Make_Loop_Parameter_Specification (Loc,
+                           Defining_Identifier => Loop_Id,
+                           Discrete_Subtype_Definition =>
+                             Make_Attribute_Reference (Loc,
+                               Prefix         => Make_Identifier (Loc, Name_V),
+                               Attribute_Name => Name_Range,
+                               Expressions    => New_List (
+                                 Make_Integer_Literal (Loc, Dim))))),
 
-            Dim := Dim - 1;
-         end loop;
+                   Statements => New_List (Init_Loop),
+                   End_Label => Empty);
 
-         --  Generate the block which contains the counter variable and the
-         --  initialization loops.
+               Dim := Dim - 1;
+            end loop;
 
-         --    declare
-         --       Counter : Integer := 0;
-         --    begin
-         --       <init loop>
-         --    end;
+            --  Generate the block which contains the counter variable and the
+            --  initialization loops.
 
-         return
-           New_List (
-             Make_Block_Statement (Loc,
+            --    declare
+            --       Counter : Integer := 0;
+            --    begin
+            --       <init loop>
+            --    end;
+
+            Init_Block :=
+              Make_Block_Statement (Loc,
                Declarations               => New_List (
                  Make_Object_Declaration (Loc,
                    Defining_Identifier => Counter_Id,
@@ -7697,7 +7746,17 @@
 
                Handled_Statement_Sequence =>
                  Make_Handled_Sequence_Of_Statements (Loc,
-                   Statements => New_List (Init_Loop))));
+                   Statements => New_List (Init_Loop)));
+
+         --  Otherwise previous errors or a missing full view may prevent the
+         --  proper freezing of the component type. If this is the case, there
+         --  is no [Deep_]Initialize primitive to call.
+
+         else
+            Init_Block := Make_Null_Statement (Loc);
+         end if;
+
+         return New_List (Init_Block);
       end Build_Initialize_Statements;
 
       -----------------------
@@ -7983,7 +8042,8 @@
          Exceptions_OK  : constant Boolean    :=
                             not Restriction_Active (No_Exception_Propagation);
          Loc            : constant Source_Ptr := Sloc (Typ);
-         Typ_Def        : constant Node_Id := Type_Definition (Parent (Typ));
+         Typ_Def        : constant Node_Id    :=
+                            Type_Definition (Parent (Typ));
 
          Bod_Stmts       : List_Id;
          Finalizer_Data  : Finalization_Exception_Data;
@@ -8002,12 +8062,7 @@
          function Process_Component_List_For_Adjust
            (Comps : Node_Id) return List_Id
          is
-            Stmts     : constant List_Id := New_List;
-            Decl      : Node_Id;
-            Decl_Id   : Entity_Id;
-            Decl_Typ  : Entity_Id;
-            Has_POC   : Boolean;
-            Num_Comps : Nat;
+            Stmts : constant List_Id := New_List;
 
             procedure Process_Component_For_Adjust (Decl : Node_Id);
             --  Process the declaration of a single controlled component
@@ -8017,10 +8072,11 @@
             ----------------------------------
 
             procedure Process_Component_For_Adjust (Decl : Node_Id) is
-               Id       : constant Entity_Id := Defining_Identifier (Decl);
-               Typ      : constant Entity_Id := Etype (Id);
-               Adj_Stmt : Node_Id;
+               Id  : constant Entity_Id := Defining_Identifier (Decl);
+               Typ : constant Entity_Id := Etype (Id);
 
+               Adj_Call : Node_Id;
+
             begin
                --    begin
                --       [Deep_]Adjust (V.Id);
@@ -8033,7 +8089,7 @@
                --          end if;
                --    end;
 
-               Adj_Stmt :=
+               Adj_Call :=
                  Make_Adjust_Call (
                    Obj_Ref =>
                      Make_Selected_Component (Loc,
@@ -8041,19 +8097,32 @@
                        Selector_Name => Make_Identifier (Loc, Chars (Id))),
                    Typ     => Typ);
 
-               if Exceptions_OK then
-                  Adj_Stmt :=
-                    Make_Block_Statement (Loc,
-                      Handled_Statement_Sequence =>
-                        Make_Handled_Sequence_Of_Statements (Loc,
-                          Statements         => New_List (Adj_Stmt),
-                          Exception_Handlers => New_List (
-                            Build_Exception_Handler (Finalizer_Data))));
+               --  Guard against a missing [Deep_]Adjust when the component
+               --  type was not properly frozen.
+
+               if Present (Adj_Call) then
+                  if Exceptions_OK then
+                     Adj_Call :=
+                       Make_Block_Statement (Loc,
+                         Handled_Statement_Sequence =>
+                           Make_Handled_Sequence_Of_Statements (Loc,
+                             Statements         => New_List (Adj_Call),
+                             Exception_Handlers => New_List (
+                               Build_Exception_Handler (Finalizer_Data))));
+                  end if;
+
+                  Append_To (Stmts, Adj_Call);
                end if;
-
-               Append_To (Stmts, Adj_Stmt);
             end Process_Component_For_Adjust;
 
+            --  Local variables
+
+            Decl      : Node_Id;
+            Decl_Id   : Entity_Id;
+            Decl_Typ  : Entity_Id;
+            Has_POC   : Boolean;
+            Num_Comps : Nat;
+
          --  Start of processing for Process_Component_List_For_Adjust
 
          begin
@@ -8389,7 +8458,8 @@
          Exceptions_OK  : constant Boolean    :=
                             not Restriction_Active (No_Exception_Propagation);
          Loc            : constant Source_Ptr := Sloc (Typ);
-         Typ_Def        : constant Node_Id := Type_Definition (Parent (Typ));
+         Typ_Def        : constant Node_Id    :=
+                            Type_Definition (Parent (Typ));
 
          Bod_Stmts       : List_Id;
          Counter         : Int := 0;
@@ -8447,7 +8517,7 @@
             is
                Id       : constant Entity_Id := Defining_Identifier (Decl);
                Typ      : constant Entity_Id := Etype (Id);
-               Fin_Stmt : Node_Id;
+               Fin_Call : Node_Id;
 
             begin
                if Is_Local then
@@ -8511,7 +8581,7 @@
                --          end if;
                --    end;
 
-               Fin_Stmt :=
+               Fin_Call :=
                  Make_Final_Call
                    (Obj_Ref =>
                       Make_Selected_Component (Loc,
@@ -8519,17 +8589,22 @@
                         Selector_Name => Make_Identifier (Loc, Chars (Id))),
                     Typ     => Typ);
 
-               if not Restriction_Active (No_Exception_Propagation) then
-                  Fin_Stmt :=
-                    Make_Block_Statement (Loc,
-                      Handled_Statement_Sequence =>
-                        Make_Handled_Sequence_Of_Statements (Loc,
-                          Statements         => New_List (Fin_Stmt),
-                          Exception_Handlers => New_List (
-                            Build_Exception_Handler (Finalizer_Data))));
+               --  Guard against a missing [Deep_]Finalize when the component
+               --  type was not properly frozen.
+
+               if Present (Fin_Call) then
+                  if Exceptions_OK then
+                     Fin_Call :=
+                       Make_Block_Statement (Loc,
+                         Handled_Statement_Sequence =>
+                           Make_Handled_Sequence_Of_Statements (Loc,
+                             Statements         => New_List (Fin_Call),
+                             Exception_Handlers => New_List (
+                               Build_Exception_Handler (Finalizer_Data))));
+                  end if;
+
+                  Append_To (Stmts, Fin_Call);
                end if;
-
-               Append_To (Stmts, Fin_Stmt);
             end Process_Component_For_Finalize;
 
          --  Start of processing for Process_Component_List_For_Finalize
@@ -9061,17 +9136,18 @@
       Utyp   : Entity_Id;
 
    begin
+      Ref := Obj_Ref;
+
       --  Recover the proper type which contains [Deep_]Finalize
 
       if Is_Class_Wide_Type (Typ) then
          Utyp := Root_Type (Typ);
          Atyp := Utyp;
-         Ref  := Obj_Ref;
 
       elsif Is_Concurrent_Type (Typ) then
          Utyp := Corresponding_Record_Type (Typ);
          Atyp := Empty;
-         Ref  := Convert_Concurrent (Obj_Ref, Typ);
+         Ref  := Convert_Concurrent (Ref, Typ);
 
       elsif Is_Private_Type (Typ)
         and then Present (Full_View (Typ))
@@ -9079,12 +9155,11 @@
       then
          Utyp := Corresponding_Record_Type (Full_View (Typ));
          Atyp := Typ;
-         Ref  := Convert_Concurrent (Obj_Ref, Full_View (Typ));
+         Ref  := Convert_Concurrent (Ref, Full_View (Typ));
 
       else
          Utyp := Typ;
          Atyp := Typ;
-         Ref  := Obj_Ref;
       end if;
 
       Utyp := Underlying_Type (Base_Type (Utyp));
@@ -9113,7 +9188,8 @@
       --  their parents. In this case, [Deep_]Finalize can be found in the full
       --  view of the parent type.
 
-      if Is_Tagged_Type (Utyp)
+      if Present (Utyp)
+        and then Is_Tagged_Type (Utyp)
         and then Is_Derived_Type (Utyp)
         and then Is_Empty_Elmt_List (Primitive_Operations (Utyp))
         and then Is_Private_Type (Etype (Utyp))
@@ -9127,7 +9203,7 @@
       --  When dealing with the completion of a private type, use the base type
       --  instead.
 
-      if Utyp /= Base_Type (Utyp) then
+      if Present (Utyp) and then Utyp /= Base_Type (Utyp) then
          pragma Assert (Present (Atyp) and then Is_Private_Type (Atyp));
 
          Utyp := Base_Type (Utyp);
@@ -9135,7 +9211,14 @@
          Set_Assignment_OK (Ref);
       end if;
 
-      if Skip_Self then
+      --  The underlying type may not be present due to a missing full view. In
+      --  this case freezing did not take place and there is no [Deep_]Finalize
+      --  primitive to call.
+
+      if No (Utyp) then
+         return Empty;
+
+      elsif Skip_Self then
          if Has_Controlled_Component (Utyp) then
             if Is_Tagged_Type (Utyp) then
                Fin_Id := Find_Optional_Prim_Op (Utyp, TSS_Deep_Finalize);
@@ -9215,7 +9298,7 @@
          return
            Make_Call (Loc,
              Proc_Id   => Fin_Id,
-             Param     => New_Copy_Tree (Ref),
+             Param     => Ref,
              Skip_Self => Skip_Self);
       else
          return Empty;
@@ -9310,18 +9393,21 @@
    ---------------------------------
 
    function Make_Finalize_Address_Stmts (Typ : Entity_Id) return List_Id is
-      Loc      : constant Source_Ptr := Sloc (Typ);
-      Ptr_Typ  : constant Entity_Id  := Make_Temporary (Loc, 'P');
-      Decls    : List_Id;
-      Desg_Typ : Entity_Id;
-      Obj_Expr : Node_Id;
+      Loc : constant Source_Ptr := Sloc (Typ);
 
+      Decls     : List_Id;
+      Desig_Typ : Entity_Id;
+      Fin_Block : Node_Id;
+      Fin_Call  : Node_Id;
+      Obj_Expr  : Node_Id;
+      Ptr_Typ   : Entity_Id;
+
    begin
       if Is_Array_Type (Typ) then
          if Is_Constrained (First_Subtype (Typ)) then
-            Desg_Typ := First_Subtype (Typ);
+            Desig_Typ := First_Subtype (Typ);
          else
-            Desg_Typ := Base_Type (Typ);
+            Desig_Typ := Base_Type (Typ);
          end if;
 
       --  Class-wide types of constrained root types
@@ -9353,26 +9439,28 @@
                Parent_Typ := Underlying_Record_View (Parent_Typ);
             end if;
 
-            Desg_Typ := Class_Wide_Type (Underlying_Type (Parent_Typ));
+            Desig_Typ := Class_Wide_Type (Underlying_Type (Parent_Typ));
          end;
 
       --  General case
 
       else
-         Desg_Typ := Typ;
+         Desig_Typ := Typ;
       end if;
 
       --  Generate:
       --    type Ptr_Typ is access all Typ;
       --    for Ptr_Typ'Storage_Size use 0;
 
+      Ptr_Typ := Make_Temporary (Loc, 'P');
+
       Decls := New_List (
         Make_Full_Type_Declaration (Loc,
           Defining_Identifier => Ptr_Typ,
           Type_Definition     =>
             Make_Access_To_Object_Definition (Loc,
               All_Present        => True,
-              Subtype_Indication => New_Occurrence_Of (Desg_Typ, Loc))),
+              Subtype_Indication => New_Occurrence_Of (Desig_Typ, Loc))),
 
         Make_Attribute_Definition_Clause (Loc,
           Name       => New_Occurrence_Of (Ptr_Typ, Loc),
@@ -9405,7 +9493,7 @@
 
             --  Generate:
             --    Dnn : constant Storage_Offset :=
-            --            Desg_Typ'Descriptor_Size / Storage_Unit;
+            --            Desig_Typ'Descriptor_Size / Storage_Unit;
 
             Dope_Id := Make_Temporary (Loc, 'D');
 
@@ -9419,7 +9507,7 @@
                   Make_Op_Divide (Loc,
                     Left_Opnd  =>
                       Make_Attribute_Reference (Loc,
-                        Prefix         => New_Occurrence_Of (Desg_Typ, Loc),
+                        Prefix         => New_Occurrence_Of (Desig_Typ, Loc),
                         Attribute_Name => Name_Descriptor_Size),
                     Right_Opnd =>
                       Make_Integer_Literal (Loc, System_Storage_Unit))));
@@ -9442,20 +9530,30 @@
          end;
       end if;
 
-      --  Create the block and the finalization call
+      Fin_Call :=
+        Make_Final_Call (
+          Obj_Ref =>
+            Make_Explicit_Dereference (Loc,
+              Prefix => Unchecked_Convert_To (Ptr_Typ, Obj_Expr)),
+          Typ     => Desig_Typ);
 
-      return New_List (
-        Make_Block_Statement (Loc,
-          Declarations => Decls,
+      if Present (Fin_Call) then
+         Fin_Block :=
+           Make_Block_Statement (Loc,
+             Declarations               => Decls,
+             Handled_Statement_Sequence =>
+               Make_Handled_Sequence_Of_Statements (Loc,
+                 Statements => New_List (Fin_Call)));
 
-          Handled_Statement_Sequence =>
-            Make_Handled_Sequence_Of_Statements (Loc,
-              Statements => New_List (
-                Make_Final_Call (
-                  Obj_Ref =>
-                    Make_Explicit_Dereference (Loc,
-                      Prefix => Unchecked_Convert_To (Ptr_Typ, Obj_Expr)),
-                  Typ => Desg_Typ)))));
+      --  Otherwise previous errors or a missing full view may prevent the
+      --  proper freezing of the designated type. If this is the case, there
+      --  is no [Deep_]Finalize primitive to call.
+
+      else
+         Fin_Block := Make_Null_Statement (Loc);
+      end if;
+
+      return New_List (Fin_Block);
    end Make_Finalize_Address_Stmts;
 
    -------------------------------------
@@ -9530,13 +9628,15 @@
       Utyp    : Entity_Id;
 
    begin
+      Ref := Obj_Ref;
+
       --  Deal with the type and object reference. Depending on the context, an
       --  object reference may need several conversions.
 
       if Is_Concurrent_Type (Typ) then
          Is_Conc := True;
          Utyp    := Corresponding_Record_Type (Typ);
-         Ref     := Convert_Concurrent (Obj_Ref, Typ);
+         Ref     := Convert_Concurrent (Ref, Typ);
 
       elsif Is_Private_Type (Typ)
         and then Present (Full_View (Typ))
@@ -9544,18 +9644,16 @@
       then
          Is_Conc := True;
          Utyp    := Corresponding_Record_Type (Underlying_Type (Typ));
-         Ref     := Convert_Concurrent (Obj_Ref, Underlying_Type (Typ));
+         Ref     := Convert_Concurrent (Ref, Underlying_Type (Typ));
 
       else
          Is_Conc := False;
          Utyp    := Typ;
-         Ref     := Obj_Ref;
       end if;
 
+      Utyp := Underlying_Type (Base_Type (Utyp));
       Set_Assignment_OK (Ref);
 
-      Utyp := Underlying_Type (Base_Type (Utyp));
-
       --  Deal with untagged derivation of private views
 
       if Is_Untagged_Derivation (Typ) and then not Is_Conc then
@@ -9571,12 +9669,20 @@
       --  completion of a private type. We need to access the base type and
       --  generate a conversion to it.
 
-      if Utyp /= Base_Type (Utyp) then
+      if Present (Utyp) and then Utyp /= Base_Type (Utyp) then
          pragma Assert (Is_Private_Type (Typ));
          Utyp := Base_Type (Utyp);
          Ref  := Unchecked_Convert_To (Utyp, Ref);
       end if;
 
+      --  The underlying type may not be present due to a missing full view.
+      --  In this case freezing did not take place and there is no suitable
+      --  [Deep_]Initialize primitive to call.
+
+      if No (Utyp) then
+         return Empty;
+      end if;
+
       --  Select the appropriate version of initialize
 
       if Has_Controlled_Component (Utyp) then
@@ -9596,8 +9702,7 @@
 
       return
         Make_Procedure_Call_Statement (Loc,
-          Name =>
-            New_Occurrence_Of (Proc, Loc),
+          Name                   => New_Occurrence_Of (Proc, Loc),
           Parameter_Associations => New_List (Ref));
    end Make_Init_Call;
 
Index: exp_ch7.ads
===================================================================
--- exp_ch7.ads (revision 244350)
+++ exp_ch7.ads (working copy)
@@ -184,10 +184,11 @@
       Typ       : Entity_Id;
       Skip_Self : Boolean := False) return Node_Id;
    --  Create a call to either Adjust or Deep_Adjust depending on the structure
-   --  of type Typ. Obj_Ref is an expression with no-side effect (not required
+   --  of type Typ. Obj_Ref is an expression with no side effects (not required
    --  to have been previously analyzed) that references the object to be
    --  adjusted. Typ is the expected type of Obj_Ref. When Skip_Self is set,
-   --  only the components (if any) are adjusted.
+   --  only the components (if any) are adjusted. Return Empty if Adjust or
+   --  Deep_Adjust is not available, possibly due to previous errors.
 
    function Make_Detach_Call (Obj_Ref : Node_Id) return Node_Id;
    --  Create a call to unhook an object from an arbitrary list. Obj_Ref is the
@@ -200,11 +201,13 @@
      (Obj_Ref   : Node_Id;
       Typ       : Entity_Id;
       Skip_Self : Boolean := False) return Node_Id;
-   --  Create a call to either Finalize or Deep_Finalize depending on the
-   --  structure of type Typ. Obj_Ref is an expression (with no-side effect
+   --  Create a call to either Finalize or Deep_Finalize, depending on the
+   --  structure of type Typ. Obj_Ref is an expression (with no side effects
    --  and is not required to have been previously analyzed) that references
    --  the object to be finalized. Typ is the expected type of Obj_Ref. When
-   --  Skip_Self is set, only the components (if any) are finalized.
+   --  Skip_Self is set, only the components (if any) are finalized. Return
+   --  Empty if Finalize or Deep_Finalize is not available, possibly due to
+   --  previous errors.
 
    procedure Make_Finalize_Address_Body (Typ : Entity_Id);
    --  Create the body of TSS routine Finalize_Address if Typ is controlled and
@@ -215,11 +218,12 @@
    function Make_Init_Call
      (Obj_Ref : Node_Id;
       Typ     : Entity_Id) return Node_Id;
-   --  Obj_Ref is an expression with no-side effect (not required to have been
-   --  previously analyzed) that references the object to be initialized. Typ
-   --  is the expected type of Obj_Ref, which is either a controlled type
-   --  (Is_Controlled) or a type with controlled components (Has_Controlled_
-   --  Components).
+   --  Create a call to either Initialize or Deep_Initialize, depending on the
+   --  structure of type Typ. Obj_Ref is an expression with no side effects
+   --  (not required to have been previously analyzed) that references the
+   --  object to be initialized. Typ is the expected type of Obj_Ref. Return
+   --  Empty if Initialize or Deep_Initialize is not available, possibly due to
+   --  previous errors.
 
    function Make_Handler_For_Ctrl_Operation (Loc : Source_Ptr) return Node_Id;
    --  Generate an implicit exception handler with an 'others' choice,
Index: exp_util.adb
===================================================================
--- exp_util.adb        (revision 244356)
+++ exp_util.adb        (working copy)
@@ -2943,7 +2943,10 @@
             Set_Etype (Obj_Ref, Desig_Typ);
          end if;
 
-         Fin_Call := Make_Final_Call (Obj_Ref, Desig_Typ);
+         Fin_Call :=
+           Make_Final_Call
+             (Obj_Ref => Obj_Ref,
+              Typ     => Desig_Typ);
 
       --  Otherwise finalize the hook. Generate:
 

Reply via email to