OSDN Git Service

Patch to fix -mcpu=G5 interface to EH runtime library.
[pf3gnuchains/gcc-fork.git] / gcc / ada / exp_aggr.adb
index a83b3b2..7bc0a76 100644 (file)
@@ -6,8 +6,7 @@
 --                                                                          --
 --                                 B o d y                                  --
 --                                                                          --
---                                                                          --
---          Copyright (C) 1992-2002 Free Software Foundation, Inc.          --
+--          Copyright (C) 1992-2004 Free Software Foundation, Inc.          --
 --                                                                          --
 -- GNAT is free software;  you can  redistribute it  and/or modify it under --
 -- terms of the  GNU General Public License as published  by the Free Soft- --
@@ -34,6 +33,8 @@ with Expander; use Expander;
 with Exp_Util; use Exp_Util;
 with Exp_Ch3;  use Exp_Ch3;
 with Exp_Ch7;  use Exp_Ch7;
+with Exp_Ch9;  use Exp_Ch9;
+with Exp_Tss;  use Exp_Tss;
 with Freeze;   use Freeze;
 with Hostparm; use Hostparm;
 with Itypes;   use Itypes;
@@ -41,6 +42,7 @@ with Lib;      use Lib;
 with Nmake;    use Nmake;
 with Nlists;   use Nlists;
 with Restrict; use Restrict;
+with Rident;   use Rident;
 with Rtsfind;  use Rtsfind;
 with Ttypes;   use Ttypes;
 with Sem;      use Sem;
@@ -71,6 +73,10 @@ package body Exp_Aggr is
    --  statement of variant part will usually be small and probably in near
    --  sorted order.
 
+   function Has_Default_Init_Comps (N : Node_Id) return Boolean;
+   --  N is an aggregate (record or array). Checks the presence of default
+   --  initialization (<>) in any component (Ada 2005: AI-287)
+
    ------------------------------------------------------
    -- Local subprograms for Record Aggregate Expansion --
    ------------------------------------------------------
@@ -98,12 +104,12 @@ package body Exp_Aggr is
    --  assignments component per component.
 
    function Build_Record_Aggr_Code
-     (N      : Node_Id;
-      Typ    : Entity_Id;
-      Target : Node_Id;
-      Flist  : Node_Id   := Empty;
-      Obj    : Entity_Id := Empty)
-      return   List_Id;
+     (N                             : Node_Id;
+      Typ                           : Entity_Id;
+      Target                        : Node_Id;
+      Flist                         : Node_Id   := Empty;
+      Obj                           : Entity_Id := Empty;
+      Is_Limited_Ancestor_Expansion : Boolean   := False) return List_Id;
    --  N is an N_Aggregate or a N_Extension_Aggregate. Typ is the type
    --  of the aggregate. Target is an expression containing the
    --  location on which the component by component assignments will
@@ -114,6 +120,13 @@ package body Exp_Aggr is
    --  object declaration and dynamic allocation cases, it contains
    --  an entity that allows to know if the value being created needs to be
    --  attached to the final list in case of pragma finalize_Storage_Only.
+   --  Is_Limited_Ancestor_Expansion indicates that the function has been
+   --  called recursively to expand the limited ancestor to avoid copying it.
+
+   function Has_Mutable_Components (Typ : Entity_Id) return Boolean;
+   --  Return true if one of the component is of a discriminated type with
+   --  defaults. An aggregate for a type with mutable components must be
+   --  expanded into individual assignments.
 
    procedure Initialize_Discriminants (N : Node_Id; Typ : Entity_Id);
    --  If the type of the aggregate is a type extension with renamed discrimi-
@@ -133,7 +146,7 @@ package body Exp_Aggr is
 
    procedure Convert_To_Positional
      (N                    : Node_Id;
-      Max_Others_Replicate : Nat := 5;
+      Max_Others_Replicate : Nat     := 5;
       Handle_Bit_Packed    : Boolean := False);
    --  If possible, convert named notation to positional notation. This
    --  conversion is possible only in some static cases. If the conversion
@@ -160,21 +173,24 @@ package body Exp_Aggr is
 
    function Build_Array_Aggr_Code
      (N           : Node_Id;
+      Ctype       : Entity_Id;
       Index       : Node_Id;
       Into        : Node_Id;
       Scalar_Comp : Boolean;
       Indices     : List_Id := No_List;
-      Flist       : Node_Id := Empty)
-      return        List_Id;
+      Flist       : Node_Id := Empty) return List_Id;
    --  This recursive routine returns a list of statements containing the
    --  loops and assignments that are needed for the expansion of the array
    --  aggregate N.
    --
-   --    N is the (sub-)aggregate node to be expanded into code.
+   --    N is the (sub-)aggregate node to be expanded into code. This node
+   --    has been fully analyzed, and its Etype is properly set.
    --
    --    Index is the index node corresponding to the array sub-aggregate N.
    --
    --    Into is the target expression into which we are copying the aggregate.
+   --    Note that this node may not have been analyzed yet, and so the Etype
+   --    field may not be set.
    --
    --    Scalar_Comp is True if the component type of the aggregate is scalar.
    --
@@ -193,8 +209,7 @@ package body Exp_Aggr is
       Typ    : Entity_Id;
       Target : Node_Id;
       Flist  : Node_Id := Empty;
-      Obj    : Entity_Id := Empty)
-      return List_Id;
+      Obj    : Entity_Id := Empty) return List_Id;
    --  N is a nested (record or array) aggregate that has been marked
    --  with 'Delay_Expansion'. Typ is the expected type of the
    --  aggregate and Target is a (duplicable) expression that will
@@ -211,8 +226,7 @@ package body Exp_Aggr is
    function Make_OK_Assignment_Statement
      (Sloc       : Source_Ptr;
       Name       : Node_Id;
-      Expression : Node_Id)
-      return       Node_Id;
+      Expression : Node_Id) return Node_Id;
    --  This is like Make_Assignment_Statement, except that Assignment_OK
    --  is set in the left operand. All assignments built by this unit
    --  use this routine. This is needed to deal with assignments to
@@ -252,6 +266,8 @@ package body Exp_Aggr is
    --    5. The array component type is tagged, which may necessitate
    --       reassignment of proper tags.
 
+   --    6. The array component type might have unaligned bit components
+
    function Backend_Processing_Possible (N : Node_Id) return Boolean is
       Typ : constant Entity_Id := Etype (N);
       --  Typ is the correct constrained array subtype of the aggregate.
@@ -305,7 +321,7 @@ package body Exp_Aggr is
          return False;
       end if;
 
-      --  Checks 4  (array must not be multi-dimensional Fortran case)
+      --  Checks 4 (array must not be multi-dimensional Fortran case)
 
       if Convention (Typ) = Convention_Fortran
         and then Number_Dimensions (Typ) > 1
@@ -338,6 +354,12 @@ package body Exp_Aggr is
          return False;
       end if;
 
+      --  Checks 6 (component type must not have bit aligned components)
+
+      if Type_May_Have_Bit_Aligned_Components (Component_Type (Typ)) then
+         return False;
+      end if;
+
       --  Backend processing is possible
 
       Set_Compile_Time_Known_Aggregate (N, True);
@@ -387,12 +409,12 @@ package body Exp_Aggr is
 
    function Build_Array_Aggr_Code
      (N           : Node_Id;
+      Ctype       : Entity_Id;
       Index       : Node_Id;
       Into        : Node_Id;
       Scalar_Comp : Boolean;
       Indices     : List_Id := No_List;
-      Flist       : Node_Id := Empty)
-      return        List_Id
+      Flist       : Node_Id := Empty) return List_Id
    is
       Loc          : constant Source_Ptr := Sloc (N);
       Index_Base   : constant Entity_Id  := Base_Type (Etype (Index));
@@ -414,13 +436,16 @@ package body Exp_Aggr is
       --  Returns a new reference to the index type name.
 
       function Gen_Assign (Ind : Node_Id; Expr : Node_Id) return List_Id;
-      --  Ind must be a side-effect free expression.
-      --  If the input aggregate N to Build_Loop contains no sub-aggregates,
-      --  This routine returns the assignment statement
+      --  Ind must be a side-effect free expression. If the input aggregate
+      --  N to Build_Loop contains no sub-aggregates, then this function
+      --  returns the assignment statement:
       --
       --     Into (Indices, Ind) := Expr;
       --
       --  Otherwise we call Build_Code recursively.
+      --
+      --  Ada 2005 (AI-287): In case of default initialized component, Expr
+      --  is empty and we generate a call to the corresponding IP subprogram.
 
       function Gen_Loop (L, H : Node_Id; Expr : Node_Id) return List_Id;
       --  Nodes L and H must be side-effect free expressions.
@@ -446,7 +471,7 @@ package body Exp_Aggr is
       --        Into (Indices, J) := Expr;
       --     end loop;
       --
-      --  Otherwise we call Build_Code recursively.
+      --  Otherwise we call Build_Code recursively
 
       function Local_Compile_Time_Known_Value (E : Node_Id) return Boolean;
       function Local_Expr_Value               (E : Node_Id) return Uint;
@@ -466,9 +491,8 @@ package body Exp_Aggr is
          Expr_Pos : Node_Id;
          Expr     : Node_Id;
          To_Pos   : Node_Id;
-
-         U_To  : Uint;
-         U_Val : Uint := UI_From_Int (Val);
+         U_To     : Uint;
+         U_Val    : constant Uint := UI_From_Int (Val);
 
       begin
          --  Note: do not try to optimize the case of Val = 0, because
@@ -626,7 +650,7 @@ package body Exp_Aggr is
       ----------------
 
       function Gen_Assign (Ind : Node_Id; Expr : Node_Id) return List_Id is
-         L : List_Id := New_List;
+         L : constant List_Id := New_List;
          F : Entity_Id;
          A : Node_Id;
 
@@ -648,7 +672,13 @@ package body Exp_Aggr is
             Res : List_Id;
 
          begin
-            if Nkind (Parent (Expr)) = N_Component_Association
+            --  Ada 2005 (AI-287): Do nothing else in case of default
+            --  initialized component.
+
+            if not Present (Expr) then
+               return Lis;
+
+            elsif Nkind (Parent (Expr)) = N_Component_Association
               and then Present (Loop_Actions (Parent (Expr)))
             then
                Append_List (Lis, Loop_Actions (Parent (Expr)));
@@ -680,32 +710,42 @@ package body Exp_Aggr is
               and then Present (Scope (Entity (Into)))
             then
                F := Find_Final_List (Scope (Entity (Into)));
-
             else
                F := Find_Final_List (Current_Scope);
             end if;
          else
-            F := 0;
+            F := Empty;
          end if;
 
          if Present (Next_Index (Index)) then
             return
               Add_Loop_Actions (
                 Build_Array_Aggr_Code
-                  (Expr, Next_Index (Index),
-                    Into, Scalar_Comp, New_Indices, F));
+                  (N           => Expr,
+                   Ctype       => Ctype,
+                   Index       => Next_Index (Index),
+                   Into        => Into,
+                   Scalar_Comp => Scalar_Comp,
+                   Indices     => New_Indices,
+                   Flist       => F));
          end if;
 
          --  If we get here then we are at a bottom-level (sub-)aggregate
 
-         Indexed_Comp :=  Checks_Off (
-             Make_Indexed_Component (Loc,
-               Prefix      => New_Copy_Tree (Into),
-               Expressions => New_Indices));
+         Indexed_Comp :=
+           Checks_Off
+             (Make_Indexed_Component (Loc,
+                Prefix      => New_Copy_Tree (Into),
+                Expressions => New_Indices));
 
          Set_Assignment_OK (Indexed_Comp);
 
-         if Nkind (Expr) = N_Qualified_Expression then
+         --  Ada 2005 (AI-287): In case of default initialized component, Expr
+         --  is not present (and therefore we also initialize Expr_Q to empty).
+
+         if not Present (Expr) then
+            Expr_Q := Empty;
+         elsif Nkind (Expr) = N_Qualified_Expression then
             Expr_Q := Expression (Expr);
          else
             Expr_Q := Expr;
@@ -715,41 +755,56 @@ package body Exp_Aggr is
            and then Etype (N) /= Any_Composite
          then
             Comp_Type := Component_Type (Etype (N));
+            pragma Assert (Comp_Type = Ctype); --  AI-287
 
          elsif Present (Next (First (New_Indices))) then
 
-            --  this is a multidimensional array. Recover the component
-            --  type from the outermost aggregate, because subaggregates
-            --  do not have an assigned type.
+            --  Ada 2005 (AI-287): Do nothing in case of default initialized
+            --  component because we have received the component type in
+            --  the formal parameter Ctype.
 
-            declare
-               P : Node_Id := Parent (Expr);
+            --  ??? Some assert pragmas have been added to check if this new
+            --      formal can be used to replace this code in all cases.
 
-            begin
-               while Present (P) loop
+            if Present (Expr) then
 
-                  if Nkind (P) = N_Aggregate
-                    and then Present (Etype (P))
-                  then
-                     Comp_Type := Component_Type (Etype (P));
-                     exit;
+               --  This is a multidimensional array. Recover the component
+               --  type from the outermost aggregate, because subaggregates
+               --  do not have an assigned type.
 
-                  else
-                     P := Parent (P);
-                  end if;
-               end loop;
-            end;
+               declare
+                  P : Node_Id := Parent (Expr);
+
+               begin
+                  while Present (P) loop
+                     if Nkind (P) = N_Aggregate
+                       and then Present (Etype (P))
+                     then
+                        Comp_Type := Component_Type (Etype (P));
+                        exit;
+
+                     else
+                        P := Parent (P);
+                     end if;
+                  end loop;
+
+                  pragma Assert (Comp_Type = Ctype); --  AI-287
+               end;
+            end if;
          end if;
 
-         if (Nkind (Expr_Q) = N_Aggregate
-           or else Nkind (Expr_Q) = N_Extension_Aggregate)
-         then
+         --  Ada 2005 (AI-287): We only analyze the expression in case of non-
+         --  default initialized components (otherwise Expr_Q is not present).
 
+         if Present (Expr_Q)
+           and then (Nkind (Expr_Q) = N_Aggregate
+                     or else Nkind (Expr_Q) = N_Extension_Aggregate)
+         then
             --  At this stage the Expression may not have been
             --  analyzed yet because the array aggregate code has not
             --  been updated to use the Expansion_Delayed flag and
             --  avoid analysis altogether to solve the same problem
-            --  (see Resolve_Aggr_Expr) so let's do the analysis of
+            --  (see Resolve_Aggr_Expr). So let us do the analysis of
             --  non-array aggregates now in order to get the value of
             --  Expansion_Delayed flag for the inner aggregate ???
 
@@ -764,59 +819,76 @@ package body Exp_Aggr is
             end if;
          end if;
 
-         --  Now generate the assignment with no associated controlled
-         --  actions since the target of the assignment may not have
-         --  been initialized, it is not possible to Finalize it as
-         --  expected by normal controlled assignment. The rest of the
-         --  controlled actions are done manually with the proper
-         --  finalization list coming from the context.
+         --  Ada 2005 (AI-287): In case of default initialized component, call
+         --  the initialization subprogram associated with the component type.
 
-         A :=
-           Make_OK_Assignment_Statement (Loc,
-             Name       => Indexed_Comp,
-             Expression => New_Copy_Tree (Expr));
+         if not Present (Expr) then
 
-         if Present (Comp_Type) and then Controlled_Type (Comp_Type) then
-            Set_No_Ctrl_Actions (A);
-         end if;
-
-         Append_To (L, A);
+            if Present (Base_Init_Proc (Etype (Ctype)))
+              or else Has_Task (Base_Type (Ctype))
+            then
+               Append_List_To (L,
+                 Build_Initialization_Call (Loc,
+                   Id_Ref            => Indexed_Comp,
+                   Typ               => Ctype,
+                   With_Default_Init => True));
+            end if;
 
-         --  Adjust the tag if tagged (because of possible view
-         --  conversions), unless compiling for the Java VM
-         --  where tags are implicit.
+         else
+            --  Now generate the assignment with no associated controlled
+            --  actions since the target of the assignment may not have
+            --  been initialized, it is not possible to Finalize it as
+            --  expected by normal controlled assignment. The rest of the
+            --  controlled actions are done manually with the proper
+            --  finalization list coming from the context.
 
-         if Present (Comp_Type)
-           and then Is_Tagged_Type (Comp_Type)
-           and then not Java_VM
-         then
             A :=
               Make_OK_Assignment_Statement (Loc,
-                Name =>
-                  Make_Selected_Component (Loc,
-                    Prefix =>  New_Copy_Tree (Indexed_Comp),
-                    Selector_Name =>
-                      New_Reference_To (Tag_Component (Comp_Type), Loc)),
+                Name       => Indexed_Comp,
+                Expression => New_Copy_Tree (Expr));
 
-                Expression =>
-                  Unchecked_Convert_To (RTE (RE_Tag),
-                    New_Reference_To (
-                      Access_Disp_Table (Comp_Type), Loc)));
+            if Present (Comp_Type) and then Controlled_Type (Comp_Type) then
+               Set_No_Ctrl_Actions (A);
+            end if;
 
             Append_To (L, A);
-         end if;
 
-         --  Adjust and Attach the component to the proper final list
-         --  which can be the controller of the outer record object or
-         --  the final list associated with the scope
+            --  Adjust the tag if tagged (because of possible view
+            --  conversions), unless compiling for the Java VM
+            --  where tags are implicit.
 
-         if Present (Comp_Type)  and then Controlled_Type (Comp_Type) then
-            Append_List_To (L,
-              Make_Adjust_Call (
-                Ref         => New_Copy_Tree (Indexed_Comp),
-                Typ         => Comp_Type,
-                Flist_Ref   => F,
-                With_Attach => Make_Integer_Literal (Loc, 1)));
+            if Present (Comp_Type)
+              and then Is_Tagged_Type (Comp_Type)
+              and then not Java_VM
+            then
+               A :=
+                 Make_OK_Assignment_Statement (Loc,
+                   Name =>
+                     Make_Selected_Component (Loc,
+                       Prefix =>  New_Copy_Tree (Indexed_Comp),
+                       Selector_Name =>
+                         New_Reference_To (Tag_Component (Comp_Type), Loc)),
+
+                   Expression =>
+                     Unchecked_Convert_To (RTE (RE_Tag),
+                       New_Reference_To (
+                         Access_Disp_Table (Comp_Type), Loc)));
+
+               Append_To (L, A);
+            end if;
+
+            --  Adjust and Attach the component to the proper final list
+            --  which can be the controller of the outer record object or
+            --  the final list associated with the scope
+
+            if Present (Comp_Type)  and then Controlled_Type (Comp_Type) then
+               Append_List_To (L,
+                 Make_Adjust_Call (
+                   Ref         => New_Copy_Tree (Indexed_Comp),
+                   Typ         => Comp_Type,
+                   Flist_Ref   => F,
+                   With_Attach => Make_Integer_Literal (Loc, 1)));
+            end if;
          end if;
 
          return Add_Loop_Actions (L);
@@ -838,8 +910,8 @@ package body Exp_Aggr is
          L_Body : List_Id;
          --  The statements to execute in the loop
 
-         S : List_Id := New_List;
-         --  list of statement
+         S : constant List_Id := New_List;
+         --  List of statements
 
          Tcopy : Node_Id;
          --  Copy of expression tree, used for checking purposes
@@ -850,21 +922,29 @@ package body Exp_Aggr is
          if Empty_Range (L, H) then
             Append_To (S, Make_Null_Statement (Loc));
 
-            --  The expression must be type-checked even though no component
-            --  of the aggregate will have this value. This is done only for
-            --  actual components of the array, not for subaggregates. Do the
-            --  check on a copy, because the expression may be shared among
-            --  several choices, some of which might be non-null.
+            --  Ada 2005 (AI-287): Nothing else need to be done in case of
+            --  default initialized component.
 
-            if Present (Etype (N))
-              and then Is_Array_Type (Etype (N))
-              and then No (Next_Index (Index))
-            then
-               Expander_Mode_Save_And_Set (False);
-               Tcopy := New_Copy_Tree (Expr);
-               Set_Parent (Tcopy, N);
-               Analyze_And_Resolve (Tcopy, Component_Type (Etype (N)));
-               Expander_Mode_Restore;
+            if not Present (Expr) then
+               null;
+
+            else
+               --  The expression must be type-checked even though no component
+               --  of the aggregate will have this value. This is done only for
+               --  actual components of the array, not for subaggregates. Do
+               --  the check on a copy, because the expression may be shared
+               --  among several choices, some of which might be non-null.
+
+               if Present (Etype (N))
+                 and then Is_Array_Type (Etype (N))
+                 and then No (Next_Index (Index))
+               then
+                  Expander_Mode_Save_And_Set (False);
+                  Tcopy := New_Copy_Tree (Expr);
+                  Set_Parent (Tcopy, N);
+                  Analyze_And_Resolve (Tcopy, Component_Type (Etype (N)));
+                  Expander_Mode_Restore;
+               end if;
             end if;
 
             return S;
@@ -884,6 +964,7 @@ package body Exp_Aggr is
            and then Local_Compile_Time_Known_Value (H)
            and then Local_Expr_Value (H) - Local_Expr_Value (L) <= 2
          then
+
             Append_List_To (S, Gen_Assign (New_Copy_Tree (L), Expr));
             Append_List_To (S, Gen_Assign (Add (1, To => L), Expr));
 
@@ -951,7 +1032,6 @@ package body Exp_Aggr is
       --     end loop;
 
       function Gen_While (L, H : Node_Id; Expr : Node_Id) return List_Id is
-
          W_J : Node_Id;
 
          W_Decl : Node_Id;
@@ -963,13 +1043,13 @@ package body Exp_Aggr is
          W_Index_Succ : Node_Id;
          --  Index_Base'Succ (J)
 
-         W_Increment  : Node_Id;
+         W_Increment : Node_Id;
          --  W_J := Index_Base'Succ (W)
 
-         W_Body : List_Id := New_List;
+         W_Body : constant List_Id := New_List;
          --  The statements to execute in the loop
 
-         S : List_Id := New_List;
+         S : constant List_Id := New_List;
          --  list of statement
 
       begin
@@ -996,7 +1076,7 @@ package body Exp_Aggr is
 
          Append_To (S, W_Decl);
 
-         --  construct " while W_J < H"
+         --  Construct " while W_J < H"
 
          W_Iteration_Scheme :=
            Make_Iteration_Scheme
@@ -1054,8 +1134,8 @@ package body Exp_Aggr is
          return Compile_Time_Known_Value (E)
            or else
              (Nkind (E) = N_Attribute_Reference
-              and then Attribute_Name (E) = Name_Val
-              and then Compile_Time_Known_Value (First (Expressions (E))));
+               and then Attribute_Name (E) = Name_Val
+               and then Compile_Time_Known_Value (First (Expressions (E))));
       end Local_Compile_Time_Known_Value;
 
       ----------------------
@@ -1076,8 +1156,10 @@ package body Exp_Aggr is
       Assoc  : Node_Id;
       Choice : Node_Id;
       Expr   : Node_Id;
+      Typ    : Entity_Id;
 
-      Others_Expr : Node_Id   := Empty;
+      Others_Expr         : Node_Id := Empty;
+      Others_Mbox_Present : Boolean := False;
 
       Aggr_L : constant Node_Id := Low_Bound (Aggregate_Bounds (N));
       Aggr_H : constant Node_Id := High_Bound (Aggregate_Bounds (N));
@@ -1085,12 +1167,12 @@ package body Exp_Aggr is
       --  the code generated by Build_Array_Aggr_Code is executed then these
       --  bounds are OK. Otherwise a Constraint_Error would have been raised.
 
-      Aggr_Low  : constant Node_Id := Duplicate_Subexpr (Aggr_L);
-      Aggr_High : constant Node_Id := Duplicate_Subexpr (Aggr_H);
-      --  After Duplicate_Subexpr these are side-effect free.
+      Aggr_Low  : constant Node_Id := Duplicate_Subexpr_No_Checks (Aggr_L);
+      Aggr_High : constant Node_Id := Duplicate_Subexpr_No_Checks (Aggr_H);
+      --  After Duplicate_Subexpr these are side-effect free
 
-      Low  : Node_Id;
-      High : Node_Id;
+      Low        : Node_Id;
+      High       : Node_Id;
 
       Nb_Choices : Nat := 0;
       Table      : Case_Table_Type (1 .. Number_Of_Choices (N));
@@ -1099,12 +1181,33 @@ package body Exp_Aggr is
       Nb_Elements : Int;
       --  Number of elements in the positional aggregate
 
-      New_Code : List_Id := New_List;
+      New_Code : constant List_Id := New_List;
 
    --  Start of processing for Build_Array_Aggr_Code
 
    begin
+      --  First before we start, a special case. if we have a bit packed
+      --  array represented as a modular type, then clear the value to
+      --  zero first, to ensure that unused bits are properly cleared.
+
+      Typ := Etype (N);
+
+      if Present (Typ)
+        and then Is_Bit_Packed_Array (Typ)
+        and then Is_Modular_Integer_Type (Packed_Array_Type (Typ))
+      then
+         Append_To (New_Code,
+           Make_Assignment_Statement (Loc,
+             Name => New_Copy_Tree (Into),
+             Expression =>
+               Unchecked_Convert_To (Typ,
+                 Make_Integer_Literal (Loc, Uint_0))));
+      end if;
+
+      --  We can skip this
       --  STEP 1: Process component associations
+      --  For those associations that may generate a loop, initialize
+      --  Loop_Actions to collect inserted actions that may be crated.
 
       if No (Expressions (N)) then
 
@@ -1112,22 +1215,35 @@ package body Exp_Aggr is
 
          Assoc := First (Component_Associations (N));
          while Present (Assoc) loop
-
             Choice := First (Choices (Assoc));
             while Present (Choice) loop
-
                if Nkind (Choice) = N_Others_Choice then
-                  Others_Expr := Expression (Assoc);
+                  Set_Loop_Actions (Assoc, New_List);
+
+                  if Box_Present (Assoc) then
+                     Others_Mbox_Present := True;
+                  else
+                     Others_Expr := Expression (Assoc);
+                  end if;
                   exit;
                end if;
 
                Get_Index_Bounds (Choice, Low, High);
 
-               Nb_Choices := Nb_Choices + 1;
-               Table (Nb_Choices) := (Choice_Lo   => Low,
-                                      Choice_Hi   => High,
-                                      Choice_Node => Expression (Assoc));
+               if Low /= High then
+                  Set_Loop_Actions (Assoc, New_List);
+               end if;
 
+               Nb_Choices := Nb_Choices + 1;
+               if Box_Present (Assoc) then
+                  Table (Nb_Choices) := (Choice_Lo   => Low,
+                                         Choice_Hi   => High,
+                                         Choice_Node => Empty);
+               else
+                  Table (Nb_Choices) := (Choice_Lo   => Low,
+                                         Choice_Hi   => High,
+                                         Choice_Node => Expression (Assoc));
+               end if;
                Next (Choice);
             end loop;
 
@@ -1148,7 +1264,6 @@ package body Exp_Aggr is
             Low  := Table (J).Choice_Lo;
             High := Table (J).Choice_Hi;
             Expr := Table (J).Choice_Node;
-
             Append_List (Gen_Loop (Low, High, Expr), To => New_Code);
          end loop;
 
@@ -1156,13 +1271,12 @@ package body Exp_Aggr is
          --  We don't need to generate loops over empty gaps, but if there is
          --  a single empty range we must analyze the expression for semantics
 
-         if Present (Others_Expr) then
+         if Present (Others_Expr) or else Others_Mbox_Present then
             declare
                First : Boolean := True;
 
             begin
                for J in 0 .. Nb_Choices loop
-
                   if J = 0 then
                      Low := Aggr_Low;
                   else
@@ -1175,7 +1289,7 @@ package body Exp_Aggr is
                      High := Add (-1, To => Table (J + 1).Choice_Lo);
                   end if;
 
-                  --  If this is an expansion within an init_proc, make
+                  --  If this is an expansion within an init proc, make
                   --  sure that discriminant references are replaced by
                   --  the corresponding discriminal.
 
@@ -1226,12 +1340,22 @@ package body Exp_Aggr is
 
          if Present (Component_Associations (N)) then
             Assoc := Last (Component_Associations (N));
-            Expr  := Expression (Assoc);
 
-            Append_List (Gen_While (Add (Nb_Elements, To => Aggr_L),
-                                    Aggr_High,
-                                    Expr),
-                         To => New_Code);
+            --  Ada 2005 (AI-287)
+
+            if Box_Present (Assoc) then
+               Append_List (Gen_While (Add (Nb_Elements, To => Aggr_L),
+                                       Aggr_High,
+                                       Empty),
+                            To => New_Code);
+            else
+               Expr  := Expression (Assoc);
+
+               Append_List (Gen_While (Add (Nb_Elements, To => Aggr_L),
+                                       Aggr_High,
+                                       Expr), --  AI-287
+                            To => New_Code);
+            end if;
          end if;
       end if;
 
@@ -1243,12 +1367,12 @@ package body Exp_Aggr is
    ----------------------------
 
    function Build_Record_Aggr_Code
-     (N      : Node_Id;
-      Typ    : Entity_Id;
-      Target : Node_Id;
-      Flist  : Node_Id   := Empty;
-      Obj    : Entity_Id := Empty)
-      return   List_Id
+     (N                             : Node_Id;
+      Typ                           : Entity_Id;
+      Target                        : Node_Id;
+      Flist                         : Node_Id   := Empty;
+      Obj                           : Entity_Id := Empty;
+      Is_Limited_Ancestor_Expansion : Boolean   := False) return List_Id
    is
       Loc     : constant Source_Ptr := Sloc (N);
       L       : constant List_Id    := New_List;
@@ -1262,7 +1386,6 @@ package body Exp_Aggr is
       Comp_Type : Entity_Id;
       Selector  : Entity_Id;
       Comp_Expr : Node_Id;
-      Comp_Kind : Node_Kind;
       Expr_Q    : Node_Id;
 
       Internal_Final_List : Node_Id;
@@ -1300,12 +1423,11 @@ package body Exp_Aggr is
          Typ     : Entity_Id;
          F       : Node_Id;
          Attach  : Node_Id;
-         Init_Pr : Boolean)
-        return List_Id;
+         Init_Pr : Boolean) return List_Id;
       --  returns the list of statements necessary to initialize the internal
       --  controller of the (possible) ancestor typ into target and attach
       --  it to finalization list F. Init_Pr conditions the call to the
-      --  init_proc since it may already be done due to ancestor initialization
+      --  init proc since it may already be done due to ancestor initialization
 
       ---------------------------------
       -- Ancestor_Discriminant_Value --
@@ -1342,6 +1464,7 @@ package body Exp_Aggr is
                      if Disc = Corresp_Disc then
                         return Duplicate_Subexpr (Expression (Assoc));
                      end if;
+
                      Corresp_Disc :=
                        Corresponding_Discriminant (Corresp_Disc);
                   end loop;
@@ -1496,36 +1619,76 @@ package body Exp_Aggr is
          Typ     : Entity_Id;
          F       : Node_Id;
          Attach  : Node_Id;
-         Init_Pr : Boolean)
-        return List_Id
+         Init_Pr : Boolean) return List_Id
       is
+         L   : constant List_Id := New_List;
          Ref : Node_Id;
-         L   : List_Id := New_List;
 
       begin
-         --     _init_proc (target._controller);
+         --  Generate:
+         --     init-proc (target._controller);
          --     initialize (target._controller);
          --     Attach_to_Final_List (target._controller, F);
 
-         Ref := Make_Selected_Component (Loc,
-                  Prefix        => Convert_To (Typ, New_Copy_Tree (Target)),
-                  Selector_Name => Make_Identifier (Loc, Name_uController));
+         Ref :=
+           Make_Selected_Component (Loc,
+             Prefix        => Convert_To (Typ, New_Copy_Tree (Target)),
+             Selector_Name => Make_Identifier (Loc, Name_uController));
          Set_Assignment_OK (Ref);
 
-         if Init_Pr then
-            Append_List_To (L,
-              Build_Initialization_Call (Loc,
-                Id_Ref       => Ref,
-                Typ          => RTE (RE_Record_Controller),
-                In_Init_Proc => Within_Init_Proc));
-         end if;
+         --  Ada 2005 (AI-287): Give support to default initialization of
+         --  limited types and components.
 
-         Append_To (L,
-           Make_Procedure_Call_Statement (Loc,
-             Name =>
-               New_Reference_To (Find_Prim_Op (RTE (RE_Record_Controller),
-                 Name_Initialize), Loc),
-             Parameter_Associations => New_List (New_Copy_Tree (Ref))));
+         if (Nkind (Target) = N_Identifier
+              and then Present (Etype (Target))
+              and then Is_Limited_Type (Etype (Target)))
+           or else
+            (Nkind (Target) = N_Selected_Component
+              and then Present (Etype (Selector_Name (Target)))
+              and then Is_Limited_Type (Etype (Selector_Name (Target))))
+           or else
+            (Nkind (Target) = N_Unchecked_Type_Conversion
+              and then Present (Etype (Target))
+              and then Is_Limited_Type (Etype (Target)))
+           or else
+            (Nkind (Target) = N_Unchecked_Expression
+              and then Nkind (Expression (Target)) = N_Indexed_Component
+              and then Present (Etype (Prefix (Expression (Target))))
+              and then Is_Limited_Type (Etype (Prefix (Expression (Target)))))
+         then
+            if Init_Pr then
+               Append_List_To (L,
+                 Build_Initialization_Call (Loc,
+                   Id_Ref       => Ref,
+                   Typ          => RTE (RE_Limited_Record_Controller),
+                   In_Init_Proc => Within_Init_Proc));
+            end if;
+
+            Append_To (L,
+              Make_Procedure_Call_Statement (Loc,
+                Name =>
+                  New_Reference_To
+                         (Find_Prim_Op (RTE (RE_Limited_Record_Controller),
+                    Name_Initialize), Loc),
+                Parameter_Associations => New_List (New_Copy_Tree (Ref))));
+
+         else
+            if Init_Pr then
+               Append_List_To (L,
+                 Build_Initialization_Call (Loc,
+                   Id_Ref       => Ref,
+                   Typ          => RTE (RE_Record_Controller),
+                   In_Init_Proc => Within_Init_Proc));
+            end if;
+
+            Append_To (L,
+              Make_Procedure_Call_Statement (Loc,
+                Name =>
+                  New_Reference_To (Find_Prim_Op (RTE (RE_Record_Controller),
+                    Name_Initialize), Loc),
+                Parameter_Associations => New_List (New_Copy_Tree (Ref))));
+
+         end if;
 
          Append_To (L,
            Make_Attach_Call (
@@ -1538,7 +1701,6 @@ package body Exp_Aggr is
    --  Start of processing for Build_Record_Aggr_Code
 
    begin
-
       --  Deal with the ancestor part of extension aggregates
       --  or with the discriminants of the root type
 
@@ -1547,14 +1709,13 @@ package body Exp_Aggr is
             A : constant Node_Id := Ancestor_Part (N);
 
          begin
-
             --  If the ancestor part is a subtype mark "T", we generate
-            --     _init_proc (T(tmp));  if T is constrained and
-            --     _init_proc (S(tmp));  where S applies an appropriate
+
+            --     init-proc (T(tmp));  if T is constrained and
+            --     init-proc (S(tmp));  where S applies an appropriate
             --                           constraint if T is unconstrained
 
             if Is_Entity_Name (A) and then Is_Type (Entity (A)) then
-
                Ancestor_Is_Subtype_Mark := True;
 
                if Is_Constrained (Entity (A)) then
@@ -1569,13 +1730,15 @@ package body Exp_Aggr is
 
                elsif Has_Discriminants (Entity (A)) then
                   declare
-                     Anc_Typ    : Entity_Id := Entity (A);
-                     Discrim    : Entity_Id := First_Discriminant (Anc_Typ);
-                     Anc_Constr : List_Id := New_List;
+                     Anc_Typ    : constant Entity_Id := Entity (A);
+                     Anc_Constr : constant List_Id   := New_List;
+                     Discrim    : Entity_Id;
                      Disc_Value : Node_Id;
                      New_Indic  : Node_Id;
                      Subt_Decl  : Node_Id;
+
                   begin
+                     Discrim := First_Discriminant (Anc_Typ);
                      while Present (Discrim) loop
                         Disc_Value := Ancestor_Discriminant_Value (Discrim);
                         Append_To (Anc_Constr, Disc_Value);
@@ -1608,11 +1771,22 @@ package body Exp_Aggr is
                Ref := Convert_To (Init_Typ, New_Copy_Tree (Target));
                Set_Assignment_OK (Ref);
 
-               Append_List_To (Start_L,
-                 Build_Initialization_Call (Loc,
-                   Id_Ref => Ref,
-                   Typ    => Init_Typ,
-                   In_Init_Proc => Within_Init_Proc));
+               if Has_Default_Init_Comps (N)
+                 or else Has_Task (Base_Type (Init_Typ))
+               then
+                  Append_List_To (Start_L,
+                    Build_Initialization_Call (Loc,
+                      Id_Ref       => Ref,
+                      Typ          => Init_Typ,
+                      In_Init_Proc => Within_Init_Proc,
+                      With_Default_Init => True));
+               else
+                  Append_List_To (Start_L,
+                    Build_Initialization_Call (Loc,
+                      Id_Ref       => Ref,
+                      Typ          => Init_Typ,
+                      In_Init_Proc => Within_Init_Proc));
+               end if;
 
                if Is_Constrained (Entity (A))
                  and then Has_Discriminants (Entity (A))
@@ -1620,6 +1794,21 @@ package body Exp_Aggr is
                   Check_Ancestor_Discriminants (Entity (A));
                end if;
 
+            --  Ada 2005 (AI-287): If the ancestor part is a limited type,
+            --  a recursive call expands the ancestor.
+
+            elsif Is_Limited_Type (Etype (A)) then
+               Ancestor_Is_Expression := True;
+
+               Append_List_To (Start_L,
+                  Build_Record_Aggr_Code (
+                    N                             => Expression (A),
+                    Typ                           => Etype (Expression (A)),
+                    Target                        => Target,
+                    Flist                         => Flist,
+                    Obj                           => Obj,
+                    Is_Limited_Ancestor_Expansion => True));
+
             --  If the ancestor part is an expression "E", we generate
             --     T(tmp) := E;
 
@@ -1677,6 +1866,8 @@ package body Exp_Aggr is
             end if;
          end;
 
+      --  Normal case (not an extension aggregate)
+
       else
          --  Generate the discriminant expressions, component by component.
          --  If the base type is an unchecked union, the discriminants are
@@ -1686,7 +1877,6 @@ package body Exp_Aggr is
          if Has_Discriminants (Typ)
            and then not Is_Unchecked_Union (Base_Type (Typ))
          then
-
             --  ??? The discriminants of the object not inherited in the type
             --  of the object should be initialized here
 
@@ -1699,7 +1889,7 @@ package body Exp_Aggr is
                Discriminant_Value : Node_Id;
 
             begin
-               Discriminant := First_Girder_Discriminant (Typ);
+               Discriminant := First_Stored_Discriminant (Typ);
 
                while Present (Discriminant) loop
 
@@ -1722,7 +1912,7 @@ package body Exp_Aggr is
                   Set_No_Ctrl_Actions (Instr);
                   Append_To (L, Instr);
 
-                  Next_Girder_Discriminant (Discriminant);
+                  Next_Stored_Discriminant (Discriminant);
                end loop;
             end;
          end if;
@@ -1736,13 +1926,62 @@ package body Exp_Aggr is
 
       Comp := First (Component_Associations (N));
       while Present (Comp) loop
-         Selector  := Entity (First (Choices (Comp)));
+         Selector := Entity (First (Choices (Comp)));
+
+         --  Ada 2005 (AI-287): Default initialization of a limited component
+
+         if Box_Present (Comp)
+            and then Is_Limited_Type (Etype (Selector))
+         then
+            --  Ada 2005 (AI-287): If the component type has tasks then
+            --  generate the activation chain and master entities (except
+            --  in case of an allocator because in that case these entities
+            --  are generated by Build_Task_Allocate_Block_With_Init_Stmts).
+
+            declare
+               Ctype            : constant Entity_Id := Etype (Selector);
+               Inside_Allocator : Boolean   := False;
+               P                : Node_Id   := Parent (N);
+
+            begin
+               if Is_Task_Type (Ctype) or else Has_Task (Ctype) then
+                  while Present (P) loop
+                     if Nkind (P) = N_Allocator then
+                        Inside_Allocator := True;
+                        exit;
+                     end if;
+
+                     P := Parent (P);
+                  end loop;
+
+                  if not Inside_Init_Proc and not Inside_Allocator then
+                     Build_Activation_Chain_Entity (N);
+
+                     if not Has_Master_Entity (Current_Scope) then
+                        Build_Master_Entity (Etype (N));
+                     end if;
+                  end if;
+               end if;
+            end;
+
+            Append_List_To (L,
+              Build_Initialization_Call (Loc,
+                Id_Ref => Make_Selected_Component (Loc,
+                            Prefix => New_Copy_Tree (Target),
+                            Selector_Name => New_Occurrence_Of (Selector,
+                                                                   Loc)),
+                Typ    => Etype (Selector),
+                With_Default_Init => True));
+
+            goto Next_Comp;
+         end if;
+
+         --  ???
 
          if Ekind (Selector) /= E_Discriminant
            or else Nkind (N) = N_Extension_Aggregate
          then
             Comp_Type := Etype (Selector);
-            Comp_Kind := Nkind (Expression (Comp));
             Comp_Expr :=
               Make_Selected_Component (Loc,
                 Prefix        => New_Copy_Tree (Target),
@@ -1765,6 +2004,7 @@ package body Exp_Aggr is
                      New_Copy_Tree (Target)),
                    Selector_Name =>
                      Make_Identifier (Loc, Name_uController));
+
                Internal_Final_List :=
                  Make_Selected_Component (Loc,
                    Prefix => Internal_Final_List,
@@ -1773,14 +2013,18 @@ package body Exp_Aggr is
                --  The internal final list can be part of a constant object
 
                Set_Assignment_OK (Internal_Final_List);
+
             else
                Internal_Final_List := Empty;
             end if;
 
+            --  ???
+
             if Is_Delayed_Aggregate (Expr_Q) then
                Append_List_To (L,
                  Late_Expansion (Expr_Q, Comp_Type, Comp_Expr,
                    Internal_Final_List));
+
             else
                Instr :=
                  Make_OK_Assignment_Statement (Loc,
@@ -1827,15 +2071,53 @@ package body Exp_Aggr is
                       With_Attach => Make_Integer_Literal (Loc, 1)));
                end if;
             end if;
+
+         --  ???
+
+         elsif Ekind (Selector) = E_Discriminant
+           and then Nkind (N) /= N_Extension_Aggregate
+           and then Nkind (Parent (N)) = N_Component_Association
+           and then Is_Constrained (Typ)
+         then
+            --  We must check that the discriminant value imposed by the
+            --  context is the same as the value given in the subaggregate,
+            --  because after the expansion into assignments there is no
+            --  record on which to perform a regular discriminant check.
+
+            declare
+               D_Val : Elmt_Id;
+               Disc  : Entity_Id;
+
+            begin
+               D_Val := First_Elmt (Discriminant_Constraint (Typ));
+               Disc  := First_Discriminant (Typ);
+
+               while Chars (Disc) /= Chars (Selector) loop
+                  Next_Discriminant (Disc);
+                  Next_Elmt (D_Val);
+               end loop;
+
+               pragma Assert (Present (D_Val));
+
+               Append_To (L,
+               Make_Raise_Constraint_Error (Loc,
+                 Condition =>
+                   Make_Op_Ne (Loc,
+                     Left_Opnd => New_Copy_Tree (Node (D_Val)),
+                     Right_Opnd => Expression (Comp)),
+                 Reason => CE_Discriminant_Check_Failed));
+            end;
          end if;
 
+         <<Next_Comp>>
+
          Next (Comp);
       end loop;
 
       --  If the type is tagged, the tag needs to be initialized (unless
       --  compiling for the Java VM where tags are implicit). It is done
       --  late in the initialization process because in some cases, we call
-      --  the init_proc of an ancestor which will not leave out the right tag
+      --  the init proc of an ancestor which will not leave out the right tag
 
       if Ancestor_Is_Expression then
          null;
@@ -1899,8 +2181,7 @@ package body Exp_Aggr is
          External_Final_List := Empty;
       end if;
 
-      --  initialize and attach the outer object in the is_controlled
-      --  case
+      --  Initialize and attach the outer object in the is_controlled case
 
       if Is_Controlled (Typ) then
          if Ancestor_Is_Subtype_Mark then
@@ -1913,33 +2194,7 @@ package body Exp_Aggr is
                 Parameter_Associations => New_List (New_Copy_Tree (Ref))));
          end if;
 
-         --  ??? when the ancestor part is an expression, the global
-         --  object is already attached at the wrong level. It should
-         --  be detached and re-attached. We have a design problem here.
-
-         if Ancestor_Is_Expression
-           and then Has_Controlled_Component (Init_Typ)
-         then
-            null;
-
-         elsif Has_Controlled_Component (Typ) then
-            F := Make_Selected_Component (Loc,
-                   Prefix        => New_Copy_Tree (Target),
-                   Selector_Name => Make_Identifier (Loc, Name_uController));
-            F := Make_Selected_Component (Loc,
-                   Prefix        => F,
-                   Selector_Name => Make_Identifier (Loc, Name_F));
-
-            Ref := New_Copy_Tree (Target);
-            Set_Assignment_OK (Ref);
-
-            Append_To (L,
-              Make_Attach_Call (
-                Obj_Ref     => Ref,
-                Flist_Ref   => F,
-                With_Attach => Make_Integer_Literal (Loc, 1)));
-
-         else --  is_Controlled (Typ) and not Has_Controlled_Component (Typ)
+         if not Has_Controlled_Component (Typ) then
             Ref := New_Copy_Tree (Target);
             Set_Assignment_OK (Ref);
             Append_To (Start_L,
@@ -1950,10 +2205,12 @@ package body Exp_Aggr is
          end if;
       end if;
 
-      --  in the Has_Controlled component case, all the intermediate
+      --  In the Has_Controlled component case, all the intermediate
       --  controllers must be initialized
 
-      if Has_Controlled_Component (Typ) then
+      if Has_Controlled_Component (Typ)
+        and not Is_Limited_Ancestor_Expansion
+      then
          declare
             Inner_Typ : Entity_Id;
             Outer_Typ : Entity_Id;
@@ -1963,7 +2220,7 @@ package body Exp_Aggr is
 
             Outer_Typ := Base_Type (Typ);
 
-            --  find outer type with a controller
+            --  Find outer type with a controller
 
             while Outer_Typ /= Init_Typ
               and then not Has_New_Controlled_Component (Outer_Typ)
@@ -1971,7 +2228,7 @@ package body Exp_Aggr is
                Outer_Typ := Etype (Outer_Typ);
             end loop;
 
-            --  attach it to the outer record controller to the
+            --  Attach it to the outer record controller to the
             --  external final list
 
             if Outer_Typ = Init_Typ then
@@ -1982,7 +2239,8 @@ package body Exp_Aggr is
                    F       => External_Final_List,
                    Attach  => Attach,
                    Init_Pr => Ancestor_Is_Expression));
-               At_Root := True;
+
+               At_Root   := True;
                Inner_Typ := Init_Typ;
 
             else
@@ -1999,6 +2257,18 @@ package body Exp_Aggr is
                  not Is_Tagged_Type (Typ) or else Inner_Typ = Outer_Typ;
             end if;
 
+            --  The outer object has to be attached as well
+
+            if Is_Controlled (Typ) then
+               Ref := New_Copy_Tree (Target);
+               Set_Assignment_OK (Ref);
+               Append_To (Start_L,
+                  Make_Attach_Call (
+                    Obj_Ref     => Ref,
+                    Flist_Ref   => New_Copy_Tree (External_Final_List),
+                    With_Attach => New_Copy_Tree (Attach)));
+            end if;
+
             --  Initialize the internal controllers for tagged types with
             --  more than one controller.
 
@@ -2009,9 +2279,11 @@ package body Exp_Aggr is
                       Prefix => Convert_To (Outer_Typ, New_Copy_Tree (Target)),
                       Selector_Name =>
                         Make_Identifier (Loc, Name_uController));
-                  F := Make_Selected_Component (Loc,
-                         Prefix => F,
-                         Selector_Name => Make_Identifier (Loc, Name_F));
+                  F :=
+                    Make_Selected_Component (Loc,
+                      Prefix => F,
+                      Selector_Name => Make_Identifier (Loc, Name_F));
+
                   Append_List_To (Start_L,
                     Init_Controller (
                       Target  => Target,
@@ -2028,7 +2300,7 @@ package body Exp_Aggr is
                Inner_Typ := Etype (Inner_Typ);
             end loop;
 
-            --  if not done yet attach the controller of the ancestor part
+            --  If not done yet attach the controller of the ancestor part
 
             if Outer_Typ /= Init_Typ
               and then Inner_Typ = Init_Typ
@@ -2038,9 +2310,10 @@ package body Exp_Aggr is
                   Make_Selected_Component (Loc,
                     Prefix => Convert_To (Outer_Typ, New_Copy_Tree (Target)),
                     Selector_Name => Make_Identifier (Loc, Name_uController));
-               F := Make_Selected_Component (Loc,
-                       Prefix => F,
-                       Selector_Name => Make_Identifier (Loc, Name_F));
+               F :=
+                  Make_Selected_Component (Loc,
+                    Prefix => F,
+                    Selector_Name => Make_Identifier (Loc, Name_F));
 
                Attach := Make_Integer_Literal (Loc, 1);
                Append_List_To (Start_L,
@@ -2066,16 +2339,35 @@ package body Exp_Aggr is
       Loc  : constant Source_Ptr := Sloc (Aggr);
       Typ  : constant Entity_Id  := Etype (Aggr);
       Temp : constant Entity_Id  := Defining_Identifier (Decl);
-      Occ  : constant Node_Id    := Unchecked_Convert_To (Typ,
-        Make_Explicit_Dereference (Loc, New_Reference_To (Temp, Loc)));
+
+      Occ  : constant Node_Id :=
+               Unchecked_Convert_To (Typ,
+                 Make_Explicit_Dereference (Loc,
+                   New_Reference_To (Temp, Loc)));
 
       Access_Type : constant Entity_Id := Etype (Temp);
 
    begin
-      Insert_Actions_After (Decl,
-        Late_Expansion (Aggr, Typ, Occ,
-          Find_Final_List (Access_Type),
-          Associated_Final_Chain (Base_Type (Access_Type))));
+      if Has_Default_Init_Comps (Aggr) then
+         declare
+            L          : constant List_Id := New_List;
+            Init_Stmts : List_Id;
+
+         begin
+            Init_Stmts := Late_Expansion (Aggr, Typ, Occ,
+                            Find_Final_List (Access_Type),
+                            Associated_Final_Chain (Base_Type (Access_Type)));
+
+            Build_Task_Allocate_Block_With_Init_Stmts (L, Aggr, Init_Stmts);
+            Insert_Actions_After (Decl, L);
+         end;
+
+      else
+         Insert_Actions_After (Decl,
+           Late_Expansion (Aggr, Typ, Occ,
+             Find_Final_List (Access_Type),
+             Associated_Final_Chain (Base_Type (Access_Type))));
+      end if;
    end Convert_Aggr_In_Allocator;
 
    --------------------------------
@@ -2083,7 +2375,7 @@ package body Exp_Aggr is
    --------------------------------
 
    procedure Convert_Aggr_In_Assignment (N : Node_Id) is
-      Aggr :          Node_Id    := Expression (N);
+      Aggr : Node_Id             := Expression (N);
       Typ  : constant Entity_Id  := Etype (Aggr);
       Occ  : constant Node_Id    := New_Copy_Tree (Name (N));
 
@@ -2103,11 +2395,82 @@ package body Exp_Aggr is
 
    procedure Convert_Aggr_In_Object_Decl (N : Node_Id) is
       Obj  : constant Entity_Id  := Defining_Identifier (N);
-      Aggr :          Node_Id    := Expression (N);
+      Aggr : Node_Id             := Expression (N);
       Loc  : constant Source_Ptr := Sloc (Aggr);
       Typ  : constant Entity_Id  := Etype (Aggr);
       Occ  : constant Node_Id    := New_Occurrence_Of (Obj, Loc);
 
+      function Discriminants_Ok return Boolean;
+      --  If the object type is constrained, the discriminants in the
+      --  aggregate must be checked against the discriminants of the subtype.
+      --  This cannot be done using Apply_Discriminant_Checks because after
+      --  expansion there is no aggregate left to check.
+
+      ----------------------
+      -- Discriminants_Ok --
+      ----------------------
+
+      function Discriminants_Ok return Boolean is
+         Cond  : Node_Id := Empty;
+         Check : Node_Id;
+         D     : Entity_Id;
+         Disc1 : Elmt_Id;
+         Disc2 : Elmt_Id;
+         Val1  : Node_Id;
+         Val2  : Node_Id;
+
+      begin
+         D := First_Discriminant (Typ);
+         Disc1 := First_Elmt (Discriminant_Constraint (Typ));
+         Disc2 := First_Elmt (Discriminant_Constraint (Etype (Obj)));
+
+         while Present (Disc1) and then Present (Disc2) loop
+            Val1 := Node (Disc1);
+            Val2 := Node (Disc2);
+
+            if not Is_OK_Static_Expression (Val1)
+              or else not Is_OK_Static_Expression (Val2)
+            then
+               Check := Make_Op_Ne (Loc,
+                 Left_Opnd  => Duplicate_Subexpr (Val1),
+                 Right_Opnd => Duplicate_Subexpr (Val2));
+
+               if No (Cond) then
+                  Cond := Check;
+
+               else
+                  Cond := Make_Or_Else (Loc,
+                    Left_Opnd => Cond,
+                    Right_Opnd => Check);
+               end if;
+
+            elsif Expr_Value (Val1) /= Expr_Value (Val2) then
+               Apply_Compile_Time_Constraint_Error (Aggr,
+                 Msg    => "incorrect value for discriminant&?",
+                 Reason => CE_Discriminant_Check_Failed,
+                 Ent    => D);
+               return False;
+            end if;
+
+            Next_Discriminant (D);
+            Next_Elmt (Disc1);
+            Next_Elmt (Disc2);
+         end loop;
+
+         --  If any discriminant constraint is non-static, emit a check.
+
+         if Present (Cond) then
+            Insert_Action (N,
+              Make_Raise_Constraint_Error (Loc,
+                Condition => Cond,
+                Reason => CE_Discriminant_Check_Failed));
+         end if;
+
+         return True;
+      end Discriminants_Ok;
+
+   --  Start of processing for Convert_Aggr_In_Object_Decl
+
    begin
       Set_Assignment_OK (Occ);
 
@@ -2115,6 +2478,14 @@ package body Exp_Aggr is
          Aggr := Expression (Aggr);
       end if;
 
+      if Has_Discriminants (Typ)
+        and then Typ /= Etype (Obj)
+        and then Is_Constrained (Etype (Obj))
+        and then not Discriminants_Ok
+      then
+         return;
+      end if;
+
       Insert_Actions_After (N, Late_Expansion (Aggr, Typ, Occ, Obj => Obj));
       Set_No_Initialization (N);
       Initialize_Discriminants (N, Typ);
@@ -2128,14 +2499,13 @@ package body Exp_Aggr is
       Loc  : constant Source_Ptr := Sloc (N);
       Temp : Entity_Id;
 
-      Instr         : Node_Id;
-      Target_Expr   : Node_Id;
-      Parent_Kind   : Node_Kind;
-      Unc_Decl      : Boolean := False;
-      Parent_Node   : Node_Id;
+      Instr       : Node_Id;
+      Target_Expr : Node_Id;
+      Parent_Kind : Node_Kind;
+      Unc_Decl    : Boolean := False;
+      Parent_Node : Node_Id;
 
    begin
-
       Parent_Node := Parent (N);
       Parent_Kind := Nkind (Parent_Node);
 
@@ -2148,24 +2518,26 @@ package body Exp_Aggr is
          begin
             Parent_Node := Parent (Parent_Node);
             Parent_Kind := Nkind (Parent_Node);
+
             if Parent_Kind = N_Object_Declaration then
                Unc_Decl :=
                  not Is_Entity_Name (Object_Definition (Parent_Node))
-                 or else Has_Discriminants (
-                   Entity (Object_Definition (Parent_Node)))
-                 or else Is_Class_Wide_Type (
-                   Entity (Object_Definition (Parent_Node)));
+                   or else Has_Discriminants
+                             (Entity (Object_Definition (Parent_Node)))
+                   or else Is_Class_Wide_Type
+                             (Entity (Object_Definition (Parent_Node)));
             end if;
          end;
       end if;
 
       --  Just set the Delay flag in the following cases where the
       --  transformation will be done top down from above
+
       --    - internal aggregate (transformed when expanding the parent)
       --    - allocators  (see Convert_Aggr_In_Allocator)
       --    - object decl (see Convert_Aggr_In_Object_Decl)
       --    - safe assignments (see Convert_Aggr_Assignments)
-      --      so far only the assignments in the init_procs are taken
+      --      so far only the assignments in the init procs are taken
       --      into account
 
       if Parent_Kind = N_Aggregate
@@ -2210,231 +2582,324 @@ package body Exp_Aggr is
 
    procedure Convert_To_Positional
      (N                    : Node_Id;
-      Max_Others_Replicate : Nat := 5;
+      Max_Others_Replicate : Nat     := 5;
       Handle_Bit_Packed    : Boolean := False)
    is
-      Loc  : constant Source_Ptr := Sloc (N);
-      Typ  : constant Entity_Id  := Etype (N);
-      Ndim : constant Pos        := Number_Dimensions (Typ);
-      Xtyp : constant Entity_Id  := Etype (First_Index (Typ));
-      Indx : constant Node_Id    := First_Index (Base_Type (Typ));
-      Blo  : constant Node_Id    := Type_Low_Bound (Etype (Indx));
-      Lo   : constant Node_Id    := Type_Low_Bound (Xtyp);
-      Hi   : constant Node_Id    := Type_High_Bound (Xtyp);
-      Lov  : Uint;
-      Hiv  : Uint;
-
-      --  The following constant determines the maximum size of an
-      --  aggregate produced by converting named to positional
-      --  notation (e.g. from others clauses). This avoids running
-      --  away with attempts to convert huge aggregates.
-
-      --  The normal limit is 5000, but we increase this limit to
-      --  2**24 (about 16 million) if Restrictions (No_Elaboration_Code)
-      --  or Restrictions (No_Implicit_Loops) is specified, since in
-      --  either case, we are at risk of declaring the program illegal
-      --  because of this limit.
-
-      Max_Aggr_Size : constant Nat :=
-         5000 + (2 ** 24 - 5000) * Boolean'Pos
-                           (Restrictions (No_Elaboration_Code)
-                              or else
-                            Restrictions (No_Implicit_Loops));
+      Typ : constant Entity_Id := Etype (N);
 
-   begin
-      --  For now, we only handle the one dimensional case and aggregates
-      --  that are not part of a component_association
+      function Flatten
+        (N   : Node_Id;
+         Ix  : Node_Id;
+         Ixb : Node_Id) return Boolean;
+      --  Convert the aggregate into a purely positional form if possible.
+
+      function Is_Flat (N : Node_Id; Dims : Int) return Boolean;
+      --  Non trivial for multidimensional aggregate.
+
+      -------------
+      -- Flatten --
+      -------------
+
+      function Flatten
+        (N   : Node_Id;
+         Ix  : Node_Id;
+         Ixb : Node_Id) return Boolean
+      is
+         Loc : constant Source_Ptr := Sloc (N);
+         Blo : constant Node_Id    := Type_Low_Bound (Etype (Ixb));
+         Lo  : constant Node_Id    := Type_Low_Bound (Etype (Ix));
+         Hi  : constant Node_Id    := Type_High_Bound (Etype (Ix));
+         Lov : Uint;
+         Hiv : Uint;
+
+         --  The following constant determines the maximum size of an
+         --  aggregate produced by converting named to positional
+         --  notation (e.g. from others clauses). This avoids running
+         --  away with attempts to convert huge aggregates.
+
+         --  The normal limit is 5000, but we increase this limit to
+         --  2**24 (about 16 million) if Restrictions (No_Elaboration_Code)
+         --  or Restrictions (No_Implicit_Loops) is specified, since in
+         --  either case, we are at risk of declaring the program illegal
+         --  because of this limit.
+
+         Max_Aggr_Size : constant Nat :=
+                           5000 + (2 ** 24 - 5000) *
+                             Boolean'Pos
+                               (Restriction_Active (No_Elaboration_Code)
+                                  or else
+                                Restriction_Active (No_Implicit_Loops));
+
+      begin
+         if Nkind (Original_Node (N)) = N_String_Literal then
+            return True;
+         end if;
+
+         --  Bounds need to be known at compile time
+
+         if not Compile_Time_Known_Value (Lo)
+           or else not Compile_Time_Known_Value (Hi)
+         then
+            return False;
+         end if;
+
+         --  Get bounds and check reasonable size (positive, not too large)
+         --  Also only handle bounds starting at the base type low bound
+         --  for now since the compiler isn't able to handle different low
+         --  bounds yet. Case such as new String'(3..5 => ' ') will get
+         --  the wrong bounds, though it seems that the aggregate should
+         --  retain the bounds set on its Etype (see C64103E and CC1311B).
+
+         Lov := Expr_Value (Lo);
+         Hiv := Expr_Value (Hi);
+
+         if Hiv < Lov
+           or else (Hiv - Lov > Max_Aggr_Size)
+           or else not Compile_Time_Known_Value (Blo)
+           or else (Lov /= Expr_Value (Blo))
+         then
+            return False;
+         end if;
+
+         --  Bounds must be in integer range (for array Vals below)
 
-      if Ndim > 1 or else Nkind (Parent (N)) = N_Aggregate
-        or else Nkind (Parent (N)) = N_Component_Association
-      then
-         return;
-      end if;
+         if not UI_Is_In_Int_Range (Lov)
+             or else
+            not UI_Is_In_Int_Range (Hiv)
+         then
+            return False;
+         end if;
 
-      --  If already positional, nothing to do!
+         --  Determine if set of alternatives is suitable for conversion
+         --  and build an array containing the values in sequence.
 
-      if No (Component_Associations (N)) then
-         return;
-      end if;
+         declare
+            Vals : array (UI_To_Int (Lov) .. UI_To_Int (Hiv))
+                     of Node_Id := (others => Empty);
+            --  The values in the aggregate sorted appropriately
 
-      --  Bounds need to be known at compile time
+            Vlist : List_Id;
+            --  Same data as Vals in list form
 
-      if not Compile_Time_Known_Value (Lo)
-        or else not Compile_Time_Known_Value (Hi)
-      then
-         return;
-      end if;
+            Rep_Count : Nat;
+            --  Used to validate Max_Others_Replicate limit
 
-      --  Normally we do not attempt to convert bit packed arrays. The
-      --  exception is when we are explicitly asked to do so (this call
-      --  is from the Packed_Array_Aggregate_Handled procedure).
+            Elmt   : Node_Id;
+            Num    : Int := UI_To_Int (Lov);
+            Choice : Node_Id;
+            Lo, Hi : Node_Id;
 
-      if Is_Bit_Packed_Array (Typ)
-        and then not Handle_Bit_Packed
-      then
-         return;
-      end if;
+         begin
+            if Present (Expressions (N)) then
+               Elmt := First (Expressions (N));
+
+               while Present (Elmt) loop
+                  if Nkind (Elmt) = N_Aggregate
+                    and then Present (Next_Index (Ix))
+                    and then
+                         not Flatten (Elmt, Next_Index (Ix), Next_Index (Ixb))
+                  then
+                     return False;
+                  end if;
 
-      --  Do not convert to positional if controlled components are
-      --  involved since these require special processing
+                  Vals (Num) := Relocate_Node (Elmt);
+                  Num := Num + 1;
 
-      if Has_Controlled_Component (Typ) then
-         return;
-      end if;
+                  Next (Elmt);
+               end loop;
+            end if;
 
-      --  Get bounds and check reasonable size (positive, not too large)
-      --  Also only handle bounds starting at the base type low bound for now
-      --  since the compiler isn't able to handle different low bounds yet.
+            if No (Component_Associations (N)) then
+               return True;
+            end if;
 
-      Lov := Expr_Value (Lo);
-      Hiv := Expr_Value (Hi);
+            Elmt := First (Component_Associations (N));
 
-      if Hiv < Lov
-        or else (Hiv - Lov > Max_Aggr_Size)
-        or else not Compile_Time_Known_Value (Blo)
-        or else (Lov /= Expr_Value (Blo))
-      then
-         return;
-      end if;
+            if Nkind (Expression (Elmt)) = N_Aggregate then
+               if Present (Next_Index (Ix))
+                 and then
+                   not Flatten
+                        (Expression (Elmt), Next_Index (Ix), Next_Index (Ixb))
+               then
+                  return False;
+               end if;
+            end if;
 
-      --  Bounds must be in integer range (for array Vals below)
+            Component_Loop : while Present (Elmt) loop
+               Choice := First (Choices (Elmt));
+               Choice_Loop : while Present (Choice) loop
+
+                  --  If we have an others choice, fill in the missing elements
+                  --  subject to the limit established by Max_Others_Replicate.
+
+                  if Nkind (Choice) = N_Others_Choice then
+                     Rep_Count := 0;
+
+                     for J in Vals'Range loop
+                        if No (Vals (J)) then
+                           Vals (J) := New_Copy_Tree (Expression (Elmt));
+                           Rep_Count := Rep_Count + 1;
+
+                           --  Check for maximum others replication. Note that
+                           --  we skip this test if either of the restrictions
+                           --  No_Elaboration_Code or No_Implicit_Loops is
+                           --  active, or if this is a preelaborable unit.
+
+                           declare
+                              P : constant Entity_Id :=
+                                    Cunit_Entity (Current_Sem_Unit);
+
+                           begin
+                              if Restriction_Active (No_Elaboration_Code)
+                                or else Restriction_Active (No_Implicit_Loops)
+                                or else Is_Preelaborated (P)
+                                or else (Ekind (P) = E_Package_Body
+                                          and then
+                                            Is_Preelaborated (Spec_Entity (P)))
+                              then
+                                 null;
+
+                              elsif Rep_Count > Max_Others_Replicate then
+                                 return False;
+                              end if;
+                           end;
+                        end if;
+                     end loop;
 
-      if not UI_Is_In_Int_Range (Lov)
-          or else
-         not UI_Is_In_Int_Range (Hiv)
-      then
-         return;
-      end if;
+                     exit Component_Loop;
 
-      --  Determine if set of alternatives is suitable for conversion
-      --  and build an array containing the values in sequence.
+                  --  Case of a subtype mark
 
-      declare
-         Vals : array (UI_To_Int (Lov) .. UI_To_Int (Hiv))
-                  of Node_Id := (others => Empty);
-         --  The values in the aggregate sorted appropriately
+                  elsif Nkind (Choice) = N_Identifier
+                    and then Is_Type (Entity (Choice))
+                  then
+                     Lo := Type_Low_Bound  (Etype (Choice));
+                     Hi := Type_High_Bound (Etype (Choice));
 
-         Vlist : List_Id;
-         --  Same data as Vals in list form
+                  --  Case of subtype indication
 
-         Rep_Count : Nat;
-         --  Used to validate Max_Others_Replicate limit
+                  elsif Nkind (Choice) = N_Subtype_Indication then
+                     Lo := Low_Bound  (Range_Expression (Constraint (Choice)));
+                     Hi := High_Bound (Range_Expression (Constraint (Choice)));
 
-         Elmt   : Node_Id;
-         Num    : Int := UI_To_Int (Lov);
-         Choice : Node_Id;
-         Lo, Hi : Node_Id;
+                  --  Case of a range
 
-      begin
-         if Present (Expressions (N)) then
-            Elmt := First (Expressions (N));
-            while Present (Elmt) loop
-               Vals (Num) := Relocate_Node (Elmt);
-               Num := Num + 1;
-               Next (Elmt);
-            end loop;
-         end if;
+                  elsif Nkind (Choice) = N_Range then
+                     Lo := Low_Bound (Choice);
+                     Hi := High_Bound (Choice);
 
-         Elmt := First (Component_Associations (N));
-         Component_Loop : while Present (Elmt) loop
+                  --  Normal subexpression case
 
-            Choice := First (Choices (Elmt));
-            Choice_Loop : while Present (Choice) loop
+                  else pragma Assert (Nkind (Choice) in N_Subexpr);
+                     if not Compile_Time_Known_Value (Choice) then
+                        return False;
 
-               --  If we have an others choice, fill in the missing elements
-               --  subject to the limit established by Max_Others_Replicate.
+                     else
+                        Vals (UI_To_Int (Expr_Value (Choice))) :=
+                          New_Copy_Tree (Expression (Elmt));
+                        goto Continue;
+                     end if;
+                  end if;
 
-               if Nkind (Choice) = N_Others_Choice then
-                  Rep_Count := 0;
+                  --  Range cases merge with Lo,Hi said
 
-                  for J in Vals'Range loop
-                     if No (Vals (J)) then
+                  if not Compile_Time_Known_Value (Lo)
+                       or else
+                     not Compile_Time_Known_Value (Hi)
+                  then
+                     return False;
+                  else
+                     for J in UI_To_Int (Expr_Value (Lo)) ..
+                              UI_To_Int (Expr_Value (Hi))
+                     loop
                         Vals (J) := New_Copy_Tree (Expression (Elmt));
-                        Rep_Count := Rep_Count + 1;
-
-                        --  Check for maximum others replication. Note that
-                        --  we skip this test if either of the restrictions
-                        --  No_Elaboration_Code or No_Implicit_Loops is
-                        --  active, or if this is a preelaborable unit.
-
-                        if Rep_Count > Max_Others_Replicate
-                          and then not Restrictions (No_Elaboration_Code)
-                          and then not Restrictions (No_Implicit_Loops)
-                          and then not
-                            Is_Preelaborated (Cunit_Entity (Current_Sem_Unit))
-                        then
-                           return;
-                        end if;
-                     end if;
-                  end loop;
+                     end loop;
+                  end if;
+
+               <<Continue>>
+                  Next (Choice);
+               end loop Choice_Loop;
 
-                  exit Component_Loop;
+               Next (Elmt);
+            end loop Component_Loop;
 
-               --  Case of a subtype mark
+            --  If we get here the conversion is possible
 
-               elsif (Nkind (Choice) = N_Identifier
-                       and then Is_Type (Entity (Choice)))
-               then
-                  Lo := Type_Low_Bound  (Etype (Choice));
-                  Hi := Type_High_Bound (Etype (Choice));
+            Vlist := New_List;
+            for J in Vals'Range loop
+               Append (Vals (J), Vlist);
+            end loop;
 
-               --  Case of subtype indication
+            Rewrite (N, Make_Aggregate (Loc, Expressions => Vlist));
+            Set_Aggregate_Bounds (N, Aggregate_Bounds (Original_Node (N)));
+            return True;
+         end;
+      end Flatten;
 
-               elsif Nkind (Choice) = N_Subtype_Indication then
-                  Lo := Low_Bound  (Range_Expression (Constraint (Choice)));
-                  Hi := High_Bound (Range_Expression (Constraint (Choice)));
+      -------------
+      -- Is_Flat --
+      -------------
 
-               --  Case of a range
+      function Is_Flat (N : Node_Id; Dims : Int) return Boolean is
+         Elmt : Node_Id;
 
-               elsif Nkind (Choice) = N_Range then
-                  Lo := Low_Bound (Choice);
-                  Hi := High_Bound (Choice);
+      begin
+         if Dims = 0 then
+            return True;
 
-               --  Normal subexpression case
+         elsif Nkind (N) = N_Aggregate then
+            if Present (Component_Associations (N)) then
+               return False;
 
-               else pragma Assert (Nkind (Choice) in N_Subexpr);
-                  if not Compile_Time_Known_Value (Choice) then
-                     return;
+            else
+               Elmt := First (Expressions (N));
 
-                  else
-                     Vals (UI_To_Int (Expr_Value (Choice))) :=
-                       New_Copy_Tree (Expression (Elmt));
-                     goto Continue;
+               while Present (Elmt) loop
+                  if not Is_Flat (Elmt, Dims - 1) then
+                     return False;
                   end if;
-               end if;
 
-               --  Range cases merge with Lo,Hi said
+                  Next (Elmt);
+               end loop;
 
-               if not Compile_Time_Known_Value (Lo)
-                    or else
-                  not Compile_Time_Known_Value (Hi)
-               then
-                  return;
-               else
-                  for J in UI_To_Int (Expr_Value (Lo)) ..
-                           UI_To_Int (Expr_Value (Hi))
-                  loop
-                     Vals (J) := New_Copy_Tree (Expression (Elmt));
-                  end loop;
-               end if;
+               return True;
+            end if;
+         else
+            return True;
+         end if;
+      end Is_Flat;
 
-            <<Continue>>
-               Next (Choice);
-            end loop Choice_Loop;
+   --  Start of processing for Convert_To_Positional
 
-            Next (Elmt);
-         end loop Component_Loop;
+   begin
+      --  Ada 2005 (AI-287): Do not convert in case of default initialized
+      --  components because in this case will need to call the corresponding
+      --  IP procedure.
 
-         --  If we get here the conversion is possible
+      if Has_Default_Init_Comps (N) then
+         return;
+      end if;
 
-         Vlist := New_List;
-         for J in Vals'Range loop
-            Append (Vals (J), Vlist);
-         end loop;
+      if Is_Flat (N, Number_Dimensions (Typ)) then
+         return;
+      end if;
+
+      if Is_Bit_Packed_Array (Typ)
+        and then not Handle_Bit_Packed
+      then
+         return;
+      end if;
+
+      --  Do not convert to positional if controlled components are
+      --  involved since these require special processing
+
+      if Has_Controlled_Component (Typ) then
+         return;
+      end if;
 
-         Rewrite (N, Make_Aggregate (Loc, Expressions => Vlist));
+      if Flatten (N, First_Index (Typ), First_Index (Base_Type (Typ))) then
          Analyze_And_Resolve (N, Typ);
-      end;
+      end if;
    end Convert_To_Positional;
 
    ----------------------------
@@ -2455,11 +2920,17 @@ package body Exp_Aggr is
    --         (c) For multidimensional arrays make sure that all subaggregates
    --             corresponding to the same dimension have the same bounds.
 
-   --  2. Check if the aggregate can be statically processed. If this is the
+   --  2. Check for packed array aggregate which can be converted to a
+   --     constant so that the aggregate disappeares completely.
+
+   --  3. Check case of nested aggregate. Generally nested aggregates are
+   --     handled during the processing of the parent aggregate.
+
+   --  4. Check if the aggregate can be statically processed. If this is the
    --     case pass it as is to Gigi. Note that a necessary condition for
    --     static processing is that the aggregate be fully positional.
 
-   --  3. If in place aggregate expansion is possible (i.e. no need to create
+   --  5. If in place aggregate expansion is possible (i.e. no need to create
    --     a temporary) then mark the aggregate as such and return. Otherwise
    --     create a new temporary and generate the appropriate initialization
    --     code.
@@ -2523,6 +2994,14 @@ package body Exp_Aggr is
       --  be done in place, because none of the new values can depend on the
       --  components of the target of the assignment.
 
+      function Must_Slide (N : Node_Id; Typ : Entity_Id) return Boolean;
+      --  A static aggregate in an object declaration can in most cases be
+      --  expanded in place. The one exception is when the aggregate is given
+      --  with component associations that specify different bounds from those
+      --  of the type definition in the object declaration. In this rather
+      --  pathological case the aggregate must slide, and we must introduce
+      --  an intermediate temporary to hold it.
+
       procedure Others_Check (Sub_Aggr : Node_Id; Dim : Pos);
       --  Checks that if an others choice is present in any sub-aggregate no
       --  aggregate index is outside the bounds of the index constraint.
@@ -2534,14 +3013,14 @@ package body Exp_Aggr is
       ----------------------------
 
       procedure Build_Constrained_Type (Positional : Boolean) is
-         Loc        : constant Source_Ptr := Sloc (N);
-         Agg_Type   : Entity_Id;
-         Comp       : Node_Id;
-         Decl       : Node_Id;
-         Typ        : constant Entity_Id := Etype (N);
-         Indices    : List_Id := New_List;
-         Num        : Int;
-         Sub_Agg    : Node_Id;
+         Loc      : constant Source_Ptr := Sloc (N);
+         Agg_Type : Entity_Id;
+         Comp     : Node_Id;
+         Decl     : Node_Id;
+         Typ      : constant Entity_Id := Etype (N);
+         Indices  : constant List_Id   := New_List;
+         Num      : Int;
+         Sub_Agg  : Node_Id;
 
       begin
          Agg_Type :=
@@ -2575,7 +3054,6 @@ package body Exp_Aggr is
             end loop;
 
          else
-
             --  We know the aggregate type is unconstrained and the
             --  aggregate is not processable by the back end, therefore
             --  not necessarily positional. Retrieve the bounds of each
@@ -2596,8 +3074,11 @@ package body Exp_Aggr is
                Type_Definition =>
                  Make_Constrained_Array_Definition (Loc,
                    Discrete_Subtype_Definitions => Indices,
-                   Subtype_Indication =>
-                     New_Occurrence_Of (Component_Type (Typ), Loc)));
+                   Component_Definition =>
+                     Make_Component_Definition (Loc,
+                       Aliased_Present => False,
+                       Subtype_Indication =>
+                         New_Occurrence_Of (Component_Type (Typ), Loc))));
 
          Insert_Action (N, Decl);
          Analyze (Decl);
@@ -2638,22 +3119,22 @@ package body Exp_Aggr is
          elsif Aggr_Hi = Ind_Hi then
             Cond :=
               Make_Op_Lt (Loc,
-                Left_Opnd  => Duplicate_Subexpr (Aggr_Lo),
-                Right_Opnd => Duplicate_Subexpr (Ind_Lo));
+                Left_Opnd  => Duplicate_Subexpr_Move_Checks (Aggr_Lo),
+                Right_Opnd => Duplicate_Subexpr_Move_Checks (Ind_Lo));
 
          elsif Aggr_Lo = Ind_Lo then
             Cond :=
               Make_Op_Gt (Loc,
-                Left_Opnd  => Duplicate_Subexpr (Aggr_Hi),
-                Right_Opnd => Duplicate_Subexpr (Ind_Hi));
+                Left_Opnd  => Duplicate_Subexpr_Move_Checks (Aggr_Hi),
+                Right_Opnd => Duplicate_Subexpr_Move_Checks (Ind_Hi));
 
          else
             Cond :=
               Make_Or_Else (Loc,
                 Left_Opnd =>
                   Make_Op_Lt (Loc,
-                    Left_Opnd  => Duplicate_Subexpr (Aggr_Lo),
-                    Right_Opnd => Duplicate_Subexpr (Ind_Lo)),
+                    Left_Opnd  => Duplicate_Subexpr_Move_Checks (Aggr_Lo),
+                    Right_Opnd => Duplicate_Subexpr_Move_Checks (Ind_Lo)),
 
                 Right_Opnd =>
                   Make_Op_Gt (Loc,
@@ -2666,8 +3147,8 @@ package body Exp_Aggr is
               Make_And_Then (Loc,
                 Left_Opnd =>
                   Make_Op_Le (Loc,
-                    Left_Opnd  => Duplicate_Subexpr (Aggr_Lo),
-                    Right_Opnd => Duplicate_Subexpr (Aggr_Hi)),
+                    Left_Opnd  => Duplicate_Subexpr_Move_Checks (Aggr_Lo),
+                    Right_Opnd => Duplicate_Subexpr_Move_Checks (Aggr_Hi)),
 
                 Right_Opnd => Cond);
 
@@ -2696,10 +3177,10 @@ package body Exp_Aggr is
          Ind_Typ : constant Entity_Id := Aggr_Index_Typ (Dim);
          --  The index type for this dimension.
 
-         Cond : Node_Id := Empty;
+         Cond  : Node_Id := Empty;
 
-         Assoc  : Node_Id;
-         Expr   : Node_Id;
+         Assoc : Node_Id;
+         Expr  : Node_Id;
 
       begin
          --  If index checks are on generate the test
@@ -2723,22 +3204,22 @@ package body Exp_Aggr is
          elsif Aggr_Hi = Sub_Hi then
             Cond :=
               Make_Op_Ne (Loc,
-                Left_Opnd  => Duplicate_Subexpr (Aggr_Lo),
-                Right_Opnd => Duplicate_Subexpr (Sub_Lo));
+                Left_Opnd  => Duplicate_Subexpr_Move_Checks (Aggr_Lo),
+                Right_Opnd => Duplicate_Subexpr_Move_Checks (Sub_Lo));
 
          elsif Aggr_Lo = Sub_Lo then
             Cond :=
               Make_Op_Ne (Loc,
-                Left_Opnd  => Duplicate_Subexpr (Aggr_Hi),
-                Right_Opnd => Duplicate_Subexpr (Sub_Hi));
+                Left_Opnd  => Duplicate_Subexpr_Move_Checks (Aggr_Hi),
+                Right_Opnd => Duplicate_Subexpr_Move_Checks (Sub_Hi));
 
          else
             Cond :=
               Make_Or_Else (Loc,
                 Left_Opnd =>
                   Make_Op_Ne (Loc,
-                    Left_Opnd  => Duplicate_Subexpr (Aggr_Lo),
-                    Right_Opnd => Duplicate_Subexpr (Sub_Lo)),
+                    Left_Opnd  => Duplicate_Subexpr_Move_Checks (Aggr_Lo),
+                    Right_Opnd => Duplicate_Subexpr_Move_Checks (Sub_Lo)),
 
                 Right_Opnd =>
                   Make_Op_Ne (Loc,
@@ -2785,8 +3266,8 @@ package body Exp_Aggr is
       ----------------------------
 
       procedure Compute_Others_Present (Sub_Aggr : Node_Id; Dim : Pos) is
-         Assoc  : Node_Id;
-         Expr   : Node_Id;
+         Assoc : Node_Id;
+         Expr  : Node_Id;
 
       begin
          if Present (Component_Associations (Sub_Aggr)) then
@@ -2824,17 +3305,16 @@ package body Exp_Aggr is
          end if;
       end Compute_Others_Present;
 
-      -------------------------
-      --  Has_Address_Clause --
-      -------------------------
+      ------------------------
+      -- Has_Address_Clause --
+      ------------------------
 
       function Has_Address_Clause (D : Node_Id) return Boolean is
-         Id   : Entity_Id := Defining_Identifier (D);
+         Id   : constant Entity_Id := Defining_Identifier (D);
          Decl : Node_Id := Next (D);
 
       begin
          while Present (Decl) loop
-
             if Nkind (Decl) = N_At_Clause
                and then Chars (Identifier (Decl)) = Chars (Id)
             then
@@ -2944,6 +3424,10 @@ package body Exp_Aggr is
             function Check_Component (Comp : Node_Id) return Boolean;
             --  Do the recursive traversal, after copy.
 
+            ---------------------
+            -- Check_Component --
+            ---------------------
+
             function Check_Component (Comp : Node_Id) return Boolean is
             begin
                if Is_Overloaded (Comp) then
@@ -2970,7 +3454,7 @@ package body Exp_Aggr is
                            and then Check_Component (Prefix (Comp)));
             end Check_Component;
 
-            --  Start of processing for Safe_Component
+         --  Start of processing for Safe_Component
 
          begin
             --  If the component appears in an association that may
@@ -3053,6 +3537,50 @@ package body Exp_Aggr is
          return Safe_Aggregate (N);
       end In_Place_Assign_OK;
 
+      ----------------
+      -- Must_Slide --
+      ----------------
+
+      function Must_Slide (N : Node_Id; Typ : Entity_Id) return Boolean
+      is
+         Obj_Type : constant Entity_Id :=
+                      Etype (Defining_Identifier (Parent (N)));
+
+         L1, L2, H1, H2 : Node_Id;
+
+      begin
+         --  No sliding if the type of the object is not established yet, if
+         --  it is an unconstrained type whose actual subtype comes from the
+         --  aggregate, or if the two types are identical.
+
+         if not Is_Array_Type (Obj_Type) then
+            return False;
+
+         elsif not Is_Constrained (Obj_Type) then
+            return False;
+
+         elsif Typ = Obj_Type then
+            return False;
+
+         else
+            --  Sliding can only occur along the first dimension
+
+            Get_Index_Bounds (First_Index (Typ), L1, H1);
+            Get_Index_Bounds (First_Index (Obj_Type), L2, H2);
+
+            if not Is_Static_Expression (L1)
+              or else not Is_Static_Expression (L2)
+              or else not Is_Static_Expression (H1)
+              or else not Is_Static_Expression (H2)
+            then
+               return False;
+            else
+               return Expr_Value (L1) /= Expr_Value (L2)
+                 or else Expr_Value (H1) /= Expr_Value (H2);
+            end if;
+         end if;
+      end Must_Slide;
+
       ------------------
       -- Others_Check --
       ------------------
@@ -3205,14 +3733,16 @@ package body Exp_Aggr is
                         Prefix         => New_Reference_To (Ind_Typ, Loc),
                         Attribute_Name => Name_Pos,
                         Expressions    =>
-                          New_List (Duplicate_Subexpr (Aggr_Lo))),
+                          New_List
+                            (Duplicate_Subexpr_Move_Checks (Aggr_Lo))),
                     Right_Opnd => Make_Integer_Literal (Loc, Nb_Elements - 1)),
 
                 Right_Opnd =>
                   Make_Attribute_Reference (Loc,
                     Prefix         => New_Reference_To (Ind_Typ, Loc),
                     Attribute_Name => Name_Pos,
-                    Expressions    => New_List (Duplicate_Subexpr (Aggr_Hi))));
+                    Expressions    => New_List (
+                      Duplicate_Subexpr_Move_Checks (Aggr_Hi))));
 
          --  If we are dealing with an aggregate containing an others
          --  choice and discrete choices we generate the following test:
@@ -3225,13 +3755,17 @@ package body Exp_Aggr is
               Make_Or_Else (Loc,
                 Left_Opnd =>
                   Make_Op_Lt (Loc,
-                    Left_Opnd  => Duplicate_Subexpr (Choices_Lo),
-                    Right_Opnd => Duplicate_Subexpr (Aggr_Lo)),
+                    Left_Opnd  =>
+                      Duplicate_Subexpr_Move_Checks (Choices_Lo),
+                    Right_Opnd =>
+                      Duplicate_Subexpr_Move_Checks (Aggr_Lo)),
 
                 Right_Opnd =>
                   Make_Op_Gt (Loc,
-                    Left_Opnd  => Duplicate_Subexpr (Choices_Hi),
-                    Right_Opnd => Duplicate_Subexpr (Aggr_Hi)));
+                    Left_Opnd  =>
+                      Duplicate_Subexpr (Choices_Hi),
+                    Right_Opnd =>
+                      Duplicate_Subexpr (Aggr_Hi)));
          end if;
 
          if Present (Cond) then
@@ -3271,10 +3805,10 @@ package body Exp_Aggr is
       --  Remaining Expand_Array_Aggregate variables
 
       Tmp : Entity_Id;
-      --  Holds the temporary aggregate value.
+      --  Holds the temporary aggregate value
 
       Tmp_Decl : Node_Id;
-      --  Holds the declaration of Tmp.
+      --  Holds the declaration of Tmp
 
       Aggr_Code   : List_Id;
       Parent_Node : Node_Id;
@@ -3298,7 +3832,10 @@ package body Exp_Aggr is
 
       pragma Assert (not Raises_Constraint_Error (N));
 
-      --  STEP 1: Check (a)
+      --  STEP 1a.
+
+      --  Check that the index range defined by aggregate bounds is
+      --  compatible with corresponding index subtype.
 
       Index_Compatibility_Check : declare
          Aggr_Index_Range : Node_Id := First_Index (Typ);
@@ -3343,11 +3880,17 @@ package body Exp_Aggr is
          end loop;
       end Index_Compatibility_Check;
 
-      --  STEP 1: Check (b)
+      --  STEP 1b.
+
+      --  If an others choice is present check that no aggregate
+      --  index is outside the bounds of the index constraint.
 
       Others_Check (N, 1);
 
-      --  STEP 1: Check (c)
+      --  STEP 1c.
+
+      --  For multidimensional arrays make sure that all subaggregates
+      --  corresponding to the same dimension have the same bounds.
 
       if Aggr_Dimension > 1 then
          Check_Same_Aggr_Bounds (N, 1);
@@ -3355,23 +3898,37 @@ package body Exp_Aggr is
 
       --  STEP 2.
 
-      --  First try to convert to positional form. If the result is not
-      --  an aggregate any more, then we are done with the analysis (it
-      --  it could be a string literal or an identifier for a temporary
-      --  variable following this call). If result is an analyzed aggregate
-      --  the transformation was also successful and we are done as well.
+      --  Here we test for is packed array aggregate that we can handle
+      --  at compile time. If so, return with transformation done. Note
+      --  that we do this even if the aggregate is nested, because once
+      --  we have done this processing, there is no more nested aggregate!
+
+      if Packed_Array_Aggregate_Handled (N) then
+         return;
+      end if;
+
+      --  At this point we try to convert to positional form
 
       Convert_To_Positional (N);
 
+      --  if the result is no longer an aggregate (e.g. it may be a string
+      --  literal, or a temporary which has the needed value), then we are
+      --  done, since there is no longer a nested aggregate.
+
       if Nkind (N) /= N_Aggregate then
          return;
 
+      --  We are also done if the result is an analyzed aggregate
+      --  This case could use more comments ???
+
       elsif Analyzed (N)
         and then N /= Original_Node (N)
       then
          return;
       end if;
 
+      --  Now see if back end processing is possible
+
       if Backend_Processing_Possible (N) then
 
          --  If the aggregate is static but the constraints are not, build
@@ -3406,6 +3963,8 @@ package body Exp_Aggr is
          return;
       end if;
 
+      --  STEP 3.
+
       --  Delay expansion for nested aggregates it will be taken care of
       --  when the parent aggregate is expanded
 
@@ -3429,17 +3988,10 @@ package body Exp_Aggr is
          return;
       end if;
 
-      --  STEP 3.
+      --  STEP 4.
 
       --  Look if in place aggregate expansion is possible
 
-      --  First case to test for is packed array aggregate that we can
-      --  handle at compile time. If so, return with transformation done.
-
-      if Packed_Array_Aggregate_Handled (N) then
-         return;
-      end if;
-
       --  For object declarations we build the aggregate in place, unless
       --  the array is bit-packed or the component is controlled.
 
@@ -3453,15 +4005,21 @@ package body Exp_Aggr is
            (N, Sec_Stack => Has_Controlled_Component (Typ));
       end if;
 
-      Maybe_In_Place_OK :=
-        Comes_From_Source (N)
-          and then Nkind (Parent (N)) = N_Assignment_Statement
-          and then not Is_Bit_Packed_Array (Typ)
-          and then not Has_Controlled_Component (Typ)
-          and then In_Place_Assign_OK;
+      if Has_Default_Init_Comps (N) then
+         Maybe_In_Place_OK := False;
+      else
+         Maybe_In_Place_OK :=
+           Comes_From_Source (N)
+             and then Nkind (Parent (N)) = N_Assignment_Statement
+             and then not Is_Bit_Packed_Array (Typ)
+             and then not Has_Controlled_Component (Typ)
+             and then In_Place_Assign_OK;
+      end if;
 
-      if Comes_From_Source (Parent (N))
+      if not Has_Default_Init_Comps (N)
+         and then Comes_From_Source (Parent (N))
          and then Nkind (Parent (N)) = N_Object_Declaration
+         and then not Must_Slide (N, Typ)
          and then N = Expression (Parent (N))
          and then not Is_Bit_Packed_Array (Typ)
          and then not Has_Controlled_Component (Typ)
@@ -3495,6 +4053,13 @@ package body Exp_Aggr is
 
          if Etype (Tmp) /= Etype (N) then
             Apply_Length_Check (N, Etype (Tmp));
+
+            if Nkind (N) = N_Raise_Constraint_Error then
+
+               --  Static error, nothing further to expand
+
+               return;
+            end if;
          end if;
 
       elsif Maybe_In_Place_OK
@@ -3515,6 +4080,10 @@ package body Exp_Aggr is
 
          return;
 
+      --  Step 5
+
+      --  In place aggregate expansion is not possible
+
       else
          Maybe_In_Place_OK := False;
          Tmp := Make_Defining_Identifier (Loc, New_Internal_Name ('A'));
@@ -3552,13 +4121,22 @@ package body Exp_Aggr is
             Target := New_Reference_To (Tmp, Loc);
 
          else
-            --  Name in assignment is explicit dereference.
+
+            if Has_Default_Init_Comps (N) then
+
+               --  Ada 2005 (AI-287): This case has not been analyzed???
+
+               raise Program_Error;
+            end if;
+
+            --  Name in assignment is explicit dereference
 
             Target := New_Copy (Tmp);
          end if;
 
          Aggr_Code :=
            Build_Array_Aggr_Code (N,
+             Ctype       => Ctyp,
              Index       => First_Index (Typ),
              Into        => Target,
              Scalar_Comp => Is_Scalar_Type (Ctyp));
@@ -3598,6 +4176,10 @@ package body Exp_Aggr is
       else
          Expand_Array_Aggregate (N);
       end if;
+
+   exception
+      when RE_Not_Available =>
+         return;
    end Expand_N_Aggregate;
 
    ----------------------------------
@@ -3617,7 +4199,7 @@ package body Exp_Aggr is
       Typ : constant Entity_Id  := Etype (N);
 
    begin
-      --  If the ancestor is a subtype mark, an init_proc must be called
+      --  If the ancestor is a subtype mark, an init proc must be called
       --  on the resulting object which thus has to be materialized in
       --  the front-end
 
@@ -3644,6 +4226,10 @@ package body Exp_Aggr is
               Parent_Expr => A);
          end if;
       end if;
+
+   exception
+      when RE_Not_Available =>
+         return;
    end Expand_N_Extension_Aggregate;
 
    -----------------------------
@@ -3655,10 +4241,10 @@ package body Exp_Aggr is
       Orig_Tag    : Node_Id := Empty;
       Parent_Expr : Node_Id := Empty)
    is
-      Loc   : constant Source_Ptr   := Sloc  (N);
-      Comps : constant List_Id      := Component_Associations (N);
-      Typ   : constant Entity_Id    := Etype (N);
-      Base_Typ : constant Entity_Id := Base_Type (Typ);
+      Loc      : constant Source_Ptr := Sloc  (N);
+      Comps    : constant List_Id    := Component_Associations (N);
+      Typ      : constant Entity_Id  := Etype (N);
+      Base_Typ : constant Entity_Id  := Base_Type (Typ);
 
       function Has_Delayed_Nested_Aggregate_Or_Tagged_Comps return Boolean;
       --  Checks the presence of a nested aggregate which needs Late_Expansion
@@ -3669,7 +4255,7 @@ package body Exp_Aggr is
       --------------------------------------------------
 
       function Has_Delayed_Nested_Aggregate_Or_Tagged_Comps return Boolean is
-         C     : Node_Id;
+         C      : Node_Id;
          Expr_Q : Node_Id;
 
       begin
@@ -3679,7 +4265,6 @@ package body Exp_Aggr is
 
          C := First (Comps);
          while Present (C) loop
-
             if Nkind (Expression (C)) = N_Qualified_Expression then
                Expr_Q := Expression (Expression (C));
             else
@@ -3711,7 +4296,7 @@ package body Exp_Aggr is
          end loop;
 
          return False;
-      end  Has_Delayed_Nested_Aggregate_Or_Tagged_Comps;
+      end Has_Delayed_Nested_Aggregate_Or_Tagged_Comps;
 
       --  Remaining Expand_Record_Aggregate variables
 
@@ -3722,6 +4307,21 @@ package body Exp_Aggr is
    --  Start of processing for Expand_Record_Aggregate
 
    begin
+      --  If the aggregate is to be assigned to an atomic variable, we
+      --  have to prevent a piecemeal assignment even if the aggregate
+      --  is to be expanded. We create a temporary for the aggregate, and
+      --  assign the temporary instead, so that the back end can generate
+      --  an atomic move for it.
+
+      if Is_Atomic (Typ)
+        and then (Nkind (Parent (N)) = N_Object_Declaration
+                    or else Nkind (Parent (N)) = N_Assignment_Statement)
+        and then Comes_From_Source (Parent (N))
+      then
+         Expand_Atomic_Aggregate (N, Typ);
+         return;
+      end if;
+
       --  Gigi doesn't handle properly temporaries of variable size
       --  so we generate it in the front-end
 
@@ -3737,6 +4337,12 @@ package body Exp_Aggr is
       then
          Convert_To_Assignments (N, Typ);
 
+         --  Ada 2005 (AI-287): In case of default initialized components we
+         --  convert the aggregate into assignments.
+
+      elsif Has_Default_Init_Comps (N) then
+         Convert_To_Assignments (N, Typ);
+
       elsif Has_Delayed_Nested_Aggregate_Or_Tagged_Comps then
          Convert_To_Assignments (N, Typ);
 
@@ -3752,6 +4358,20 @@ package body Exp_Aggr is
       elsif Is_Tagged_Type (Typ) and then Has_Discriminants (Typ) then
          Convert_To_Assignments (N, Typ);
 
+      --  If some components are mutable, the size of the aggregate component
+      --  may be disctinct from the default size of the type component, so
+      --  we need to expand to insure that the back-end copies the proper
+      --  size of the data.
+
+      elsif Has_Mutable_Components (Typ) then
+         Convert_To_Assignments (N, Typ);
+
+      --  If the type involved has any non-bit aligned components, then
+      --  we are not sure that the back end can handle this case correctly.
+
+      elsif Type_May_Have_Bit_Aligned_Components (Typ) then
+         Convert_To_Assignments (N, Typ);
+
       --  In all other cases we generate a proper aggregate that
       --  can be handled by gigi.
 
@@ -3765,29 +4385,29 @@ package body Exp_Aggr is
 
          elsif Is_Derived_Type (Typ) then
 
-            --  For untagged types,  non-girder discriminants are replaced
-            --  with girder discriminants, which are the ones that gigi uses
+            --  For untagged types,  non-stored discriminants are replaced
+            --  with stored discriminants, which are the ones that gigi uses
             --  to describe the type and its components.
 
             Generate_Aggregate_For_Derived_Type : declare
+               Constraints  : constant List_Id := New_List;
                First_Comp   : Node_Id;
                Discriminant : Entity_Id;
-               Constraints  : List_Id := New_List;
                Decl         : Node_Id;
                Num_Disc     : Int := 0;
                Num_Gird     : Int := 0;
 
-               procedure Prepend_Girder_Values (T : Entity_Id);
-               --  Scan the list of girder discriminants of the type, and
+               procedure Prepend_Stored_Values (T : Entity_Id);
+               --  Scan the list of stored discriminants of the type, and
                --  add their values to the aggregate being built.
 
                ---------------------------
-               -- Prepend_Girder_Values --
+               -- Prepend_Stored_Values --
                ---------------------------
 
-               procedure Prepend_Girder_Values (T : Entity_Id) is
+               procedure Prepend_Stored_Values (T : Entity_Id) is
                begin
-                  Discriminant := First_Girder_Discriminant (T);
+                  Discriminant := First_Stored_Discriminant (T);
 
                   while Present (Discriminant) loop
                      New_Comp :=
@@ -3809,9 +4429,9 @@ package body Exp_Aggr is
                      end if;
 
                      First_Comp := New_Comp;
-                     Next_Girder_Discriminant (Discriminant);
+                     Next_Stored_Discriminant (Discriminant);
                   end loop;
-               end Prepend_Girder_Values;
+               end Prepend_Stored_Values;
 
             --  Start of processing for Generate_Aggregate_For_Derived_Type
 
@@ -3833,25 +4453,25 @@ package body Exp_Aggr is
                   end if;
                end loop;
 
-               --  Insert girder discriminant associations in the correct
-               --  order. If there are more girder discriminants than new
+               --  Insert stored discriminant associations in the correct
+               --  order. If there are more stored discriminants than new
                --  discriminants, there is at least one new discriminant
-               --  that constrains more than one of the girders. In this
-               --  case we need to construct a proper subtype of the parent
-               --  type, in order to supply values to all the components.
-               --  Otherwise there is one-one correspondence between the
-               --  constraints and the girder discriminants.
+               --  that constrains more than one of the stored discriminants.
+               --  In this case we need to construct a proper subtype of
+               --  the parent type, in order to supply values to all the
+               --  components. Otherwise there is one-one correspondence
+               --  between the constraints and the stored discriminants.
 
                First_Comp := Empty;
 
-               Discriminant := First_Girder_Discriminant (Base_Type (Typ));
+               Discriminant := First_Stored_Discriminant (Base_Type (Typ));
 
                while Present (Discriminant) loop
                   Num_Gird := Num_Gird + 1;
-                  Next_Girder_Discriminant (Discriminant);
+                  Next_Stored_Discriminant (Discriminant);
                end loop;
 
-               --  Case of more girder discriminants than new discriminants
+               --  Case of more stored discriminants than new discriminants
 
                if Num_Gird > Num_Disc then
 
@@ -3859,7 +4479,7 @@ package body Exp_Aggr is
                   --  the proper implementation type for the aggregate, and
                   --  convert it to the intended target type.
 
-                  Discriminant := First_Girder_Discriminant (Base_Type (Typ));
+                  Discriminant := First_Stored_Discriminant (Base_Type (Typ));
 
                   while Present (Discriminant) loop
                      New_Comp :=
@@ -3869,7 +4489,7 @@ package body Exp_Aggr is
                              Typ,
                              Discriminant_Constraint (Typ)));
                      Append (New_Comp, Constraints);
-                     Next_Girder_Discriminant (Discriminant);
+                     Next_Stored_Discriminant (Discriminant);
                   end loop;
 
                   Decl :=
@@ -3886,7 +4506,7 @@ package body Exp_Aggr is
                               (Loc, Constraints)));
 
                   Insert_Action (N, Decl);
-                  Prepend_Girder_Values (Base_Type (Typ));
+                  Prepend_Stored_Values (Base_Type (Typ));
 
                   Set_Etype (N, Defining_Identifier (Decl));
                   Set_Analyzed (N);
@@ -3895,11 +4515,11 @@ package body Exp_Aggr is
                   Analyze (N);
 
                --  Case where we do not have fewer new discriminants than
-               --  girder discriminants, so in this case we can simply
-               --  use the girder discriminants of the subtype.
+               --  stored discriminants, so in this case we can simply
+               --  use the stored discriminants of the subtype.
 
                else
-                  Prepend_Girder_Values (Typ);
+                  Prepend_Stored_Values (Typ);
                end if;
             end Generate_Aggregate_For_Derived_Type;
          end if;
@@ -4049,13 +4669,61 @@ package body Exp_Aggr is
       end if;
    end Expand_Record_Aggregate;
 
+   ----------------------------
+   -- Has_Default_Init_Comps --
+   ----------------------------
+
+   function Has_Default_Init_Comps (N : Node_Id) return Boolean is
+      Comps : constant List_Id := Component_Associations (N);
+      C     : Node_Id;
+      Expr  : Node_Id;
+   begin
+      pragma Assert (Nkind (N) = N_Aggregate
+         or else Nkind (N) = N_Extension_Aggregate);
+
+      if No (Comps) then
+         return False;
+      end if;
+
+      --  Check if any direct component has default initialized components
+
+      C := First (Comps);
+      while Present (C) loop
+         if Box_Present (C) then
+            return True;
+         end if;
+
+         Next (C);
+      end loop;
+
+      --  Recursive call in case of aggregate expression
+
+      C := First (Comps);
+      while Present (C) loop
+         Expr := Expression (C);
+
+         if Present (Expr)
+           and then (Nkind (Expr) = N_Aggregate
+                     or else Nkind (Expr) = N_Extension_Aggregate)
+           and then Has_Default_Init_Comps (Expr)
+         then
+            return True;
+         end if;
+
+         Next (C);
+      end loop;
+
+      return False;
+   end Has_Default_Init_Comps;
+
    --------------------------
    -- Is_Delayed_Aggregate --
    --------------------------
 
    function Is_Delayed_Aggregate (N : Node_Id) return Boolean is
-      Node : Node_Id := N;
+      Node : Node_Id   := N;
       Kind : Node_Kind := Nkind (Node);
+
    begin
       if Kind = N_Qualified_Expression then
          Node := Expression (Node);
@@ -4077,23 +4745,23 @@ package body Exp_Aggr is
      (N      : Node_Id;
       Typ    : Entity_Id;
       Target : Node_Id;
-      Flist  : Node_Id := Empty;
-      Obj    : Entity_Id := Empty)
-
-      return   List_Id is
-
+      Flist  : Node_Id   := Empty;
+      Obj    : Entity_Id := Empty) return List_Id
+   is
    begin
       if Is_Record_Type (Etype (N)) then
          return Build_Record_Aggr_Code (N, Typ, Target, Flist, Obj);
-      else
+
+      else pragma Assert (Is_Array_Type (Etype (N)));
          return
            Build_Array_Aggr_Code
-             (N,
-              First_Index (Typ),
-              Target,
-              Is_Scalar_Type (Component_Type (Typ)),
-              No_List,
-              Flist);
+             (N           => N,
+              Ctype       => Component_Type (Etype (N)),
+              Index       => First_Index (Typ),
+              Into        => Target,
+              Scalar_Comp => Is_Scalar_Type (Component_Type (Typ)),
+              Indices     => No_List,
+              Flist       => Flist);
       end if;
    end Late_Expansion;
 
@@ -4104,8 +4772,7 @@ package body Exp_Aggr is
    function Make_OK_Assignment_Statement
      (Sloc       : Source_Ptr;
       Name       : Node_Id;
-      Expression : Node_Id)
-      return       Node_Id
+      Expression : Node_Id) return Node_Id
    is
    begin
       Set_Assignment_OK (Name);
@@ -4207,9 +4874,13 @@ package body Exp_Aggr is
 
             Analyze_And_Resolve (N, Ctyp);
 
-            --  Must have a compile time value
+            --  Must have a compile time value. String literals have to
+            --  be converted into temporaries as well, because they cannot
+            --  easily be converted into their bit representation.
 
-            if not Compile_Time_Known_Value (N) then
+            if not Compile_Time_Known_Value (N)
+              or else Nkind (N) = N_String_Literal
+            then
                raise Not_Handled;
             end if;
 
@@ -4316,14 +4987,19 @@ package body Exp_Aggr is
 
             --  Loop to set the values
 
-            Aggregate_Val := Uint_0;
-            Expr := First (Expressions (N));
-            for J in 1 .. Len loop
-               Aggregate_Val :=
-                 Aggregate_Val + Get_Component_Val (Expr) * Uint_2 ** Shift;
-               Shift := Shift + Incr;
-               Next (Expr);
-            end loop;
+            if Len = 0 then
+               Aggregate_Val := Uint_0;
+            else
+               Expr := First (Expressions (N));
+               Aggregate_Val := Get_Component_Val (Expr) * Uint_2 ** Shift;
+
+               for J in 2 .. Len loop
+                  Shift := Shift + Incr;
+                  Next (Expr);
+                  Aggregate_Val :=
+                    Aggregate_Val + Get_Component_Val (Expr) * Uint_2 ** Shift;
+               end loop;
+            end if;
 
             --  Now we can rewrite with the proper value
 
@@ -4355,6 +5031,30 @@ package body Exp_Aggr is
          return False;
    end Packed_Array_Aggregate_Handled;
 
+   ----------------------------
+   -- Has_Mutable_Components --
+   ----------------------------
+
+   function Has_Mutable_Components (Typ : Entity_Id) return Boolean is
+      Comp : Entity_Id;
+
+   begin
+      Comp := First_Component (Typ);
+
+      while Present (Comp) loop
+         if Is_Record_Type (Etype (Comp))
+           and then Has_Discriminants (Etype (Comp))
+           and then not Is_Constrained (Etype (Comp))
+         then
+            return True;
+         end if;
+
+         Next_Component (Comp);
+      end loop;
+
+      return False;
+   end Has_Mutable_Components;
+
    ------------------------------
    -- Initialize_Discriminants --
    ------------------------------
@@ -4379,7 +5079,7 @@ package body Exp_Aggr is
         and then Nkind (N) /= N_Extension_Aggregate
       then
 
-         --   Call init_proc to set discriminants.
+         --   Call init proc to set discriminants.
          --   There should eventually be a special procedure for this ???
 
          Ref := New_Reference_To (Defining_Identifier (N), Loc);
@@ -4439,6 +5139,11 @@ package body Exp_Aggr is
               Iteration_Scheme => L_Iter,
               Statements       => New_List (L_Body));
 
+         --  Set type of aggregate to be type of lhs in assignment,
+         --  to suppress redundant length checks.
+
+         Set_Etype (N, Etype (Name (Parent (N))));
+
          Rewrite (Parent (N), Stat);
          Analyze (Parent (N));
          return True;
@@ -4453,8 +5158,8 @@ package body Exp_Aggr is
    ---------------------
 
    procedure Sort_Case_Table (Case_Table : in out Case_Table_Type) is
-      L : Int := Case_Table'First;
-      U : Int := Case_Table'Last;
+      L : constant Int := Case_Table'First;
+      U : constant Int := Case_Table'Last;
       K : Int;
       J : Int;
       T : Case_Bounds;