------------------------------------------------------------------------------
--                                                                          --
--                         GNAT COMPILER COMPONENTS                         --
--                                                                          --
--                              E X P _ C H 5                               --
--                                                                          --
--                                 B o d y                                  --
--                                                                          --
--          Copyright (C) 1992-2021, 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- --
-- ware  Foundation;  either version 3,  or (at your option) any later ver- --
-- sion.  GNAT is distributed in the hope that it will be useful, but WITH- --
-- OUT ANY WARRANTY;  without even the  implied warranty of MERCHANTABILITY --
-- or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License --
-- for  more details.  You should have  received  a copy of the GNU General --
-- Public License  distributed with GNAT; see file COPYING3.  If not, go to --
-- http://www.gnu.org/licenses for a complete copy of the license.          --
--                                                                          --
-- GNAT was originally developed  by the GNAT team at  New York University. --
-- Extensive contributions were provided by Ada Core Technologies Inc.      --
--                                                                          --
------------------------------------------------------------------------------

with Aspects;        use Aspects;
with Atree;          use Atree;
with Checks;         use Checks;
with Debug;          use Debug;
with Einfo;          use Einfo;
with Einfo.Entities; use Einfo.Entities;
with Einfo.Utils;    use Einfo.Utils;
with Elists;         use Elists;
with Exp_Aggr;       use Exp_Aggr;
with Exp_Ch6;        use Exp_Ch6;
with Exp_Ch7;        use Exp_Ch7;
with Exp_Ch11;       use Exp_Ch11;
with Exp_Dbug;       use Exp_Dbug;
with Exp_Pakd;       use Exp_Pakd;
with Exp_Tss;        use Exp_Tss;
with Exp_Util;       use Exp_Util;
with Expander;       use Expander;
with Inline;         use Inline;
with Namet;          use Namet;
with Nlists;         use Nlists;
with Nmake;          use Nmake;
with Opt;            use Opt;
with Restrict;       use Restrict;
with Rident;         use Rident;
with Rtsfind;        use Rtsfind;
with Sinfo;          use Sinfo;
with Sinfo.Nodes;    use Sinfo.Nodes;
with Sinfo.Utils;    use Sinfo.Utils;
with Sem;            use Sem;
with Sem_Aux;        use Sem_Aux;
with Sem_Ch3;        use Sem_Ch3;
with Sem_Ch8;        use Sem_Ch8;
with Sem_Ch13;       use Sem_Ch13;
with Sem_Eval;       use Sem_Eval;
with Sem_Res;        use Sem_Res;
with Sem_Util;       use Sem_Util;
with Snames;         use Snames;
with Stand;          use Stand;
with Stringt;        use Stringt;
with Tbuild;         use Tbuild;
with Ttypes;         use Ttypes;
with Uintp;          use Uintp;
with Validsw;        use Validsw;

package body Exp_Ch5 is

   procedure Build_Formal_Container_Iteration
     (N         : Node_Id;
      Container : Entity_Id;
      Cursor    : Entity_Id;
      Init      : out Node_Id;
      Advance   : out Node_Id;
      New_Loop  : out Node_Id);
   --  Utility to create declarations and loop statement for both forms
   --  of formal container iterators.

   function Convert_To_Iterable_Type
     (Container : Entity_Id;
      Loc       : Source_Ptr) return Node_Id;
   --  Returns New_Occurrence_Of (Container), possibly converted to an ancestor
   --  type, if the type of Container inherited the Iterable aspect from that
   --  ancestor.

   function Change_Of_Representation (N : Node_Id) return Boolean;
   --  Determine if the right-hand side of assignment N is a type conversion
   --  which requires a change of representation. Called only for the array
   --  and record cases.

   procedure Expand_Assign_Array (N : Node_Id; Rhs : Node_Id);
   --  N is an assignment which assigns an array value. This routine process
   --  the various special cases and checks required for such assignments,
   --  including change of representation. Rhs is normally simply the right-
   --  hand side of the assignment, except that if the right-hand side is a
   --  type conversion or a qualified expression, then the RHS is the actual
   --  expression inside any such type conversions or qualifications.

   function Expand_Assign_Array_Loop
     (N      : Node_Id;
      Larray : Entity_Id;
      Rarray : Entity_Id;
      L_Type : Entity_Id;
      R_Type : Entity_Id;
      Ndim   : Pos;
      Rev    : Boolean) return Node_Id;
   --  N is an assignment statement which assigns an array value. This routine
   --  expands the assignment into a loop (or nested loops for the case of a
   --  multi-dimensional array) to do the assignment component by component.
   --  Larray and Rarray are the entities of the actual arrays on the left-hand
   --  and right-hand sides. L_Type and R_Type are the types of these arrays
   --  (which may not be the same, due to either sliding, or to a change of
   --  representation case). Ndim is the number of dimensions and the parameter
   --  Rev indicates if the loops run normally (Rev = False), or reversed
   --  (Rev = True). The value returned is the constructed loop statement.
   --  Auxiliary declarations are inserted before node N using the standard
   --  Insert_Actions mechanism.

   function Expand_Assign_Array_Bitfield
     (N      : Node_Id;
      Larray : Entity_Id;
      Rarray : Entity_Id;
      L_Type : Entity_Id;
      R_Type : Entity_Id;
      Rev    : Boolean) return Node_Id;
   --  Alternative to Expand_Assign_Array_Loop for packed bitfields. Generates
   --  a call to System.Bitfields.Copy_Bitfield, which is more efficient than
   --  copying component-by-component.

   function Expand_Assign_Array_Bitfield_Fast
     (N      : Node_Id;
      Larray : Entity_Id;
      Rarray : Entity_Id) return Node_Id;
   --  Alternative to Expand_Assign_Array_Bitfield. Generates a call to
   --  System.Bitfields.Fast_Copy_Bitfield, which is more efficient than
   --  Copy_Bitfield, but only works in restricted situations.

   function Expand_Assign_Array_Loop_Or_Bitfield
     (N      : Node_Id;
      Larray : Entity_Id;
      Rarray : Entity_Id;
      L_Type : Entity_Id;
      R_Type : Entity_Id;
      Ndim   : Pos;
      Rev    : Boolean) return Node_Id;
   --  Calls either Expand_Assign_Array_Loop, Expand_Assign_Array_Bitfield, or
   --  Expand_Assign_Array_Bitfield_Fast as appropriate.

   procedure Expand_Assign_Record (N : Node_Id);
   --  N is an assignment of an untagged record value. This routine handles
   --  the case where the assignment must be made component by component,
   --  either because the target is not byte aligned, or there is a change
   --  of representation, or when we have a tagged type with a representation
   --  clause (this last case is required because holes in the tagged type
   --  might be filled with components from child types).

   procedure Expand_Assign_With_Target_Names (N : Node_Id);
   --  (AI12-0125): N is an assignment statement whose RHS contains occurrences
   --  of @ that designate the value of the LHS of the assignment. If the LHS
   --  is side-effect free the target names can be replaced with a copy of the
   --  LHS; otherwise the semantics of the assignment is described in terms of
   --  a procedure with an in-out parameter, and expanded as such.

   procedure Expand_Formal_Container_Loop (N : Node_Id);
   --  Use the primitives specified in an Iterable aspect to expand a loop
   --  over a so-called formal container, primarily for SPARK usage.

   procedure Expand_Formal_Container_Element_Loop (N : Node_Id);
   --  Same, for an iterator of the form " For E of C". In this case the
   --  iterator provides the name of the element, and the cursor is generated
   --  internally.

   procedure Expand_Iterator_Loop (N : Node_Id);
   --  Expand loop over arrays and containers that uses the form "for X of C"
   --  with an optional subtype mark, or "for Y in C".

   procedure Expand_Iterator_Loop_Over_Container
     (N             : Node_Id;
      Isc           : Node_Id;
      I_Spec        : Node_Id;
      Container     : Node_Id;
      Container_Typ : Entity_Id);
   --  Expand loop over containers that uses the form "for X of C" with an
   --  optional subtype mark, or "for Y in C". Isc is the iteration scheme.
   --  I_Spec is the iterator specification and Container is either the
   --  Container (for OF) or the iterator (for IN).

   procedure Expand_Predicated_Loop (N : Node_Id);
   --  Expand for loop over predicated subtype

   function Make_Tag_Ctrl_Assignment (N : Node_Id) return List_Id;
   --  Generate the necessary code for controlled and tagged assignment, that
   --  is to say, finalization of the target before, adjustment of the target
   --  after and save and restore of the tag and finalization pointers which
   --  are not 'part of the value' and must not be changed upon assignment. N
   --  is the original Assignment node.

   --------------------------------------
   -- Build_Formal_Container_Iteration --
   --------------------------------------

   procedure Build_Formal_Container_Iteration
     (N         : Node_Id;
      Container : Entity_Id;
      Cursor    : Entity_Id;
      Init      : out Node_Id;
      Advance   : out Node_Id;
      New_Loop  : out Node_Id)
   is
      Loc   : constant Source_Ptr := Sloc (N);
      Stats : constant List_Id    := Statements (N);
      Typ   : constant Entity_Id  := Base_Type (Etype (Container));

      Has_Element_Op : constant Entity_Id :=
                         Get_Iterable_Type_Primitive (Typ, Name_Has_Element);

      First_Op : Entity_Id;
      Next_Op  : Entity_Id;

   begin
      --  Use the proper set of primitives depending on the direction of
      --  iteration. The legality of a reverse iteration has been checked
      --  during analysis.

      if Reverse_Present (Iterator_Specification (Iteration_Scheme (N))) then
         First_Op := Get_Iterable_Type_Primitive (Typ, Name_Last);
         Next_Op  := Get_Iterable_Type_Primitive (Typ, Name_Previous);

      else
         First_Op := Get_Iterable_Type_Primitive (Typ, Name_First);
         Next_Op  := Get_Iterable_Type_Primitive (Typ, Name_Next);
      end if;

      --  Declaration for Cursor

      Init :=
        Make_Object_Declaration (Loc,
          Defining_Identifier => Cursor,
          Object_Definition   => New_Occurrence_Of (Etype (First_Op),  Loc),
          Expression          =>
            Make_Function_Call (Loc,
              Name                   => New_Occurrence_Of (First_Op, Loc),
              Parameter_Associations => New_List (
                Convert_To_Iterable_Type (Container, Loc))));

      --  Statement that advances (in the right direction) cursor in loop

      Advance :=
        Make_Assignment_Statement (Loc,
          Name       => New_Occurrence_Of (Cursor, Loc),
          Expression =>
            Make_Function_Call (Loc,
              Name                   => New_Occurrence_Of (Next_Op, Loc),
              Parameter_Associations => New_List (
                Convert_To_Iterable_Type (Container, Loc),
                New_Occurrence_Of (Cursor, Loc))));

      --  Iterator is rewritten as a while_loop

      New_Loop :=
        Make_Loop_Statement (Loc,
          Iteration_Scheme =>
            Make_Iteration_Scheme (Loc,
              Condition =>
                Make_Function_Call (Loc,
                  Name => New_Occurrence_Of (Has_Element_Op, Loc),
                  Parameter_Associations => New_List (
                    Convert_To_Iterable_Type (Container, Loc),
                    New_Occurrence_Of (Cursor, Loc)))),
          Statements => Stats,
          End_Label  => Empty);

      --  If the contruct has a specified loop name, preserve it in the new
      --  loop, for possible use in exit statements.

      if Present (Identifier (N))
        and then Comes_From_Source (Identifier (N))
      then
         Set_Identifier (New_Loop, Identifier (N));
      end if;
   end Build_Formal_Container_Iteration;

   ------------------------------
   -- Change_Of_Representation --
   ------------------------------

   function Change_Of_Representation (N : Node_Id) return Boolean is
      Rhs : constant Node_Id := Expression (N);
   begin
      return
        Nkind (Rhs) = N_Type_Conversion
          and then not Has_Compatible_Representation
                         (Target_Type  => Etype (Rhs),
                          Operand_Type => Etype (Expression (Rhs)));
   end Change_Of_Representation;

   ------------------------------
   -- Convert_To_Iterable_Type --
   ------------------------------

   function Convert_To_Iterable_Type
     (Container : Entity_Id;
      Loc       : Source_Ptr) return Node_Id
   is
      Typ    : constant Entity_Id := Base_Type (Etype (Container));
      Aspect : constant Node_Id   := Find_Aspect (Typ, Aspect_Iterable);
      Result : Node_Id;

   begin
      Result := New_Occurrence_Of (Container, Loc);

      if Entity (Aspect) /= Typ then
         Result :=
           Make_Type_Conversion (Loc,
             Subtype_Mark => New_Occurrence_Of (Entity (Aspect), Loc),
             Expression   => Result);
      end if;

      return Result;
   end Convert_To_Iterable_Type;

   -------------------------
   -- Expand_Assign_Array --
   -------------------------

   --  There are two issues here. First, do we let Gigi do a block move, or
   --  do we expand out into a loop? Second, we need to set the two flags
   --  Forwards_OK and Backwards_OK which show whether the block move (or
   --  corresponding loops) can be legitimately done in a forwards (low to
   --  high) or backwards (high to low) manner.

   procedure Expand_Assign_Array (N : Node_Id; Rhs : Node_Id) is
      Loc : constant Source_Ptr := Sloc (N);

      Lhs : constant Node_Id := Name (N);

      Act_Lhs : constant Node_Id := Get_Referenced_Object (Lhs);
      Act_Rhs : Node_Id          := Get_Referenced_Object (Rhs);

      L_Type : constant Entity_Id :=
                 Underlying_Type (Get_Actual_Subtype (Act_Lhs));
      R_Type : Entity_Id :=
                 Underlying_Type (Get_Actual_Subtype (Act_Rhs));

      L_Slice : constant Boolean := Nkind (Act_Lhs) = N_Slice;
      R_Slice : constant Boolean := Nkind (Act_Rhs) = N_Slice;

      Crep : constant Boolean := Change_Of_Representation (N);

      pragma Assert
        (Crep
          or else Is_Bit_Packed_Array (L_Type) = Is_Bit_Packed_Array (R_Type));

      Larray  : Node_Id;
      Rarray  : Node_Id;

      Ndim : constant Pos := Number_Dimensions (L_Type);

      Loop_Required : Boolean := False;
      --  This switch is set to True if the array move must be done using
      --  an explicit front end generated loop.

      procedure Apply_Dereference (Arg : Node_Id);
      --  If the argument is an access to an array, and the assignment is
      --  converted into a procedure call, apply explicit dereference.

      function Has_Address_Clause (Exp : Node_Id) return Boolean;
      --  Test if Exp is a reference to an array whose declaration has
      --  an address clause, or it is a slice of such an array.

      function Is_Formal_Array (Exp : Node_Id) return Boolean;
      --  Test if Exp is a reference to an array which is either a formal
      --  parameter or a slice of a formal parameter. These are the cases
      --  where hidden aliasing can occur.

      function Is_Non_Local_Array (Exp : Node_Id) return Boolean;
      --  Determine if Exp is a reference to an array variable which is other
      --  than an object defined in the current scope, or a component or a
      --  slice of such an object. Such objects can be aliased to parameters
      --  (unlike local array references).

      -----------------------
      -- Apply_Dereference --
      -----------------------

      procedure Apply_Dereference (Arg : Node_Id) is
         Typ : constant Entity_Id := Etype (Arg);
      begin
         if Is_Access_Type (Typ) then
            Rewrite (Arg, Make_Explicit_Dereference (Loc,
              Prefix => Relocate_Node (Arg)));
            Analyze_And_Resolve (Arg, Designated_Type (Typ));
         end if;
      end Apply_Dereference;

      ------------------------
      -- Has_Address_Clause --
      ------------------------

      function Has_Address_Clause (Exp : Node_Id) return Boolean is
      begin
         return
           (Is_Entity_Name (Exp) and then
                              Present (Address_Clause (Entity (Exp))))
             or else
           (Nkind (Exp) = N_Slice and then Has_Address_Clause (Prefix (Exp)));
      end Has_Address_Clause;

      ---------------------
      -- Is_Formal_Array --
      ---------------------

      function Is_Formal_Array (Exp : Node_Id) return Boolean is
      begin
         return
           (Is_Entity_Name (Exp) and then Is_Formal (Entity (Exp)))
             or else
           (Nkind (Exp) = N_Slice and then Is_Formal_Array (Prefix (Exp)));
      end Is_Formal_Array;

      ------------------------
      -- Is_Non_Local_Array --
      ------------------------

      function Is_Non_Local_Array (Exp : Node_Id) return Boolean is
      begin
         case Nkind (Exp) is
            when N_Indexed_Component
               | N_Selected_Component
               | N_Slice
            =>
               return Is_Non_Local_Array (Prefix (Exp));

            when others =>
               return
                 not (Is_Entity_Name (Exp)
                       and then Scope (Entity (Exp)) = Current_Scope);
         end case;
      end Is_Non_Local_Array;

      --  Determine if Lhs, Rhs are formal arrays or nonlocal arrays

      Lhs_Formal : constant Boolean := Is_Formal_Array (Act_Lhs);
      Rhs_Formal : constant Boolean := Is_Formal_Array (Act_Rhs);

      Lhs_Non_Local_Var : constant Boolean := Is_Non_Local_Array (Act_Lhs);
      Rhs_Non_Local_Var : constant Boolean := Is_Non_Local_Array (Act_Rhs);

   --  Start of processing for Expand_Assign_Array

   begin
      --  Deal with length check. Note that the length check is done with
      --  respect to the right-hand side as given, not a possible underlying
      --  renamed object, since this would generate incorrect extra checks.

      Apply_Length_Check_On_Assignment (Rhs, L_Type, Lhs);

      --  We start by assuming that the move can be done in either direction,
      --  i.e. that the two sides are completely disjoint.

      Set_Forwards_OK  (N, True);
      Set_Backwards_OK (N, True);

      --  Normally it is only the slice case that can lead to overlap, and
      --  explicit checks for slices are made below. But there is one case
      --  where the slice can be implicit and invisible to us: when we have a
      --  one dimensional array, and either both operands are parameters, or
      --  one is a parameter (which can be a slice passed by reference) and the
      --  other is a non-local variable. In this case the parameter could be a
      --  slice that overlaps with the other operand.

      --  However, if the array subtype is a constrained first subtype in the
      --  parameter case, then we don't have to worry about overlap, since
      --  slice assignments aren't possible (other than for a slice denoting
      --  the whole array).

      --  Note: No overlap is possible if there is a change of representation,
      --  so we can exclude this case.

      if Ndim = 1
        and then not Crep
        and then
           ((Lhs_Formal and Rhs_Formal)
              or else
            (Lhs_Formal and Rhs_Non_Local_Var)
              or else
            (Rhs_Formal and Lhs_Non_Local_Var))
        and then
           (not Is_Constrained (Etype (Lhs))
             or else not Is_First_Subtype (Etype (Lhs)))
      then
         Set_Forwards_OK  (N, False);
         Set_Backwards_OK (N, False);

         --  Note: the bit-packed case is not worrisome here, since if we have
         --  a slice passed as a parameter, it is always aligned on a byte
         --  boundary, and if there are no explicit slices, the assignment
         --  can be performed directly.
      end if;

      --  If either operand has an address clause clear Backwards_OK and
      --  Forwards_OK, since we cannot tell if the operands overlap. We
      --  exclude this treatment when Rhs is an aggregate, since we know
      --  that overlap can't occur.

      if (Has_Address_Clause (Lhs) and then Nkind (Rhs) /= N_Aggregate)
        or else Has_Address_Clause (Rhs)
      then
         Set_Forwards_OK  (N, False);
         Set_Backwards_OK (N, False);
      end if;

      --  We certainly must use a loop for change of representation and also
      --  we use the operand of the conversion on the right-hand side as the
      --  effective right-hand side (the component types must match in this
      --  situation).

      if Crep then
         Act_Rhs := Get_Referenced_Object (Rhs);
         R_Type  := Get_Actual_Subtype (Act_Rhs);
         Loop_Required := True;

      --  We require a loop if the left side is possibly bit unaligned

      elsif Possible_Bit_Aligned_Component (Lhs)
              or else
            Possible_Bit_Aligned_Component (Rhs)
      then
         Loop_Required := True;

      --  Arrays with controlled components are expanded into a loop to force
      --  calls to Adjust at the component level.

      elsif Has_Controlled_Component (L_Type) then
         Loop_Required := True;

      --  If object is full access, we cannot tolerate a loop

      elsif Is_Full_Access_Object (Act_Lhs)
              or else
            Is_Full_Access_Object (Act_Rhs)
      then
         return;

      --  Loop is required if we have atomic components since we have to
      --  be sure to do any accesses on an element by element basis.

      elsif Has_Atomic_Components (L_Type)
        or else Has_Atomic_Components (R_Type)
        or else Is_Full_Access (Component_Type (L_Type))
        or else Is_Full_Access (Component_Type (R_Type))
      then
         Loop_Required := True;

      --  Case where no slice is involved

      elsif not L_Slice and not R_Slice then

         --  The following code deals with the case of unconstrained bit packed
         --  arrays. The problem is that the template for such arrays contains
         --  the bounds of the actual source level array, but the copy of an
         --  entire array requires the bounds of the underlying array. It would
         --  be nice if the back end could take care of this, but right now it
         --  does not know how, so if we have such a type, then we expand out
         --  into a loop, which is inefficient but works correctly. If we don't
         --  do this, we get the wrong length computed for the array to be
         --  moved. The two cases we need to worry about are:

         --  Explicit dereference of an unconstrained packed array type as in
         --  the following example:

         --    procedure C52 is
         --       type BITS is array(INTEGER range <>) of BOOLEAN;
         --       pragma PACK(BITS);
         --       type A is access BITS;
         --       P1,P2 : A;
         --    begin
         --       P1 := new BITS (1 .. 65_535);
         --       P2 := new BITS (1 .. 65_535);
         --       P2.ALL := P1.ALL;
         --    end C52;

         --  A formal parameter reference with an unconstrained bit array type
         --  is the other case we need to worry about (here we assume the same
         --  BITS type declared above):

         --    procedure Write_All (File : out BITS; Contents : BITS);
         --    begin
         --       File.Storage := Contents;
         --    end Write_All;

         --  We expand to a loop in either of these two cases

         --  Question for future thought. Another potentially more efficient
         --  approach would be to create the actual subtype, and then do an
         --  unchecked conversion to this actual subtype ???

         Check_Unconstrained_Bit_Packed_Array : declare

            function Is_UBPA_Reference (Opnd : Node_Id) return Boolean;
            --  Function to perform required test for the first case, above
            --  (dereference of an unconstrained bit packed array).

            -----------------------
            -- Is_UBPA_Reference --
            -----------------------

            function Is_UBPA_Reference (Opnd : Node_Id) return Boolean is
               Typ      : constant Entity_Id := Underlying_Type (Etype (Opnd));
               P_Type   : Entity_Id;
               Des_Type : Entity_Id;

            begin
               if Present (Packed_Array_Impl_Type (Typ))
                 and then Is_Array_Type (Packed_Array_Impl_Type (Typ))
                 and then not Is_Constrained (Packed_Array_Impl_Type (Typ))
               then
                  return True;

               elsif Nkind (Opnd) = N_Explicit_Dereference then
                  P_Type := Underlying_Type (Etype (Prefix (Opnd)));

                  if not Is_Access_Type (P_Type) then
                     return False;

                  else
                     Des_Type := Designated_Type (P_Type);
                     return
                       Is_Bit_Packed_Array (Des_Type)
                         and then not Is_Constrained (Des_Type);
                  end if;

               else
                  return False;
               end if;
            end Is_UBPA_Reference;

         --  Start of processing for Check_Unconstrained_Bit_Packed_Array

         begin
            if Is_UBPA_Reference (Lhs)
                 or else
               Is_UBPA_Reference (Rhs)
            then
               Loop_Required := True;

            --  Here if we do not have the case of a reference to a bit packed
            --  unconstrained array case. In this case gigi can most certainly
            --  handle the assignment if a forwards move is allowed.

            --  (could it handle the backwards case also???)

            elsif Forwards_OK (N) then
               return;
            end if;
         end Check_Unconstrained_Bit_Packed_Array;

      --  The back end can always handle the assignment if the right side is a
      --  string literal (note that overlap is definitely impossible in this
      --  case). If the type is packed, a string literal is always converted
      --  into an aggregate, except in the case of a null slice, for which no
      --  aggregate can be written. In that case, rewrite the assignment as a
      --  null statement, a length check has already been emitted to verify
      --  that the range of the left-hand side is empty.

      --  Note that this code is not executed if we have an assignment of a
      --  string literal to a non-bit aligned component of a record, a case
      --  which cannot be handled by the backend.

      elsif Nkind (Rhs) = N_String_Literal then
         if String_Length (Strval (Rhs)) = 0
           and then Is_Bit_Packed_Array (L_Type)
         then
            Rewrite (N, Make_Null_Statement (Loc));
            Analyze (N);
         end if;

         return;

      --  If either operand is bit packed, then we need a loop, since we can't
      --  be sure that the slice is byte aligned. Similarly, if either operand
      --  is a possibly unaligned slice, then we need a loop (since the back
      --  end cannot handle unaligned slices).

      elsif Is_Bit_Packed_Array (L_Type)
        or else Is_Bit_Packed_Array (R_Type)
        or else Is_Possibly_Unaligned_Slice (Lhs)
        or else Is_Possibly_Unaligned_Slice (Rhs)
      then
         Loop_Required := True;

      --  If we are not bit-packed, and we have only one slice, then no overlap
      --  is possible except in the parameter case, so we can let the back end
      --  handle things.

      elsif not (L_Slice and R_Slice) then
         if Forwards_OK (N) then
            return;
         end if;
      end if;

      --  If the right-hand side is a string literal, introduce a temporary for
      --  it, for use in the generated loop that will follow.

      if Nkind (Rhs) = N_String_Literal then
         declare
            Temp : constant Entity_Id := Make_Temporary (Loc, 'T', Rhs);
            Decl : Node_Id;

         begin
            Decl :=
              Make_Object_Declaration (Loc,
                 Defining_Identifier => Temp,
                 Object_Definition => New_Occurrence_Of (L_Type, Loc),
                 Expression => Relocate_Node (Rhs));

            Insert_Action (N, Decl);
            Rewrite (Rhs, New_Occurrence_Of (Temp, Loc));
            R_Type := Etype (Temp);
         end;
      end if;

      --  Come here to complete the analysis

      --    Loop_Required: Set to True if we know that a loop is required
      --                   regardless of overlap considerations.

      --    Forwards_OK:   Set to False if we already know that a forwards
      --                   move is not safe, else set to True.

      --    Backwards_OK:  Set to False if we already know that a backwards
      --                   move is not safe, else set to True

      --  Our task at this stage is to complete the overlap analysis, which can
      --  result in possibly setting Forwards_OK or Backwards_OK to False, and
      --  then generating the final code, either by deciding that it is OK
      --  after all to let Gigi handle it, or by generating appropriate code
      --  in the front end.

      declare
         L_Index_Typ : constant Entity_Id := Etype (First_Index (L_Type));
         R_Index_Typ : constant Entity_Id := Etype (First_Index (R_Type));

         Left_Lo  : constant Node_Id := Type_Low_Bound  (L_Index_Typ);
         Left_Hi  : constant Node_Id := Type_High_Bound (L_Index_Typ);
         Right_Lo : constant Node_Id := Type_Low_Bound  (R_Index_Typ);
         Right_Hi : constant Node_Id := Type_High_Bound (R_Index_Typ);

         Act_L_Array : Node_Id;
         Act_R_Array : Node_Id;

         Cleft_Lo  : Node_Id;
         Cright_Lo : Node_Id;
         Condition : Node_Id;

         Cresult : Compare_Result;

      begin
         --  Get the expressions for the arrays. If we are dealing with a
         --  private type, then convert to the underlying type. We can do
         --  direct assignments to an array that is a private type, but we
         --  cannot assign to elements of the array without this extra
         --  unchecked conversion.

         --  Note: We propagate Parent to the conversion nodes to generate
         --  a well-formed subtree.

         if Nkind (Act_Lhs) = N_Slice then
            Larray := Prefix (Act_Lhs);
         else
            Larray := Act_Lhs;

            if Is_Private_Type (Etype (Larray)) then
               declare
                  Par : constant Node_Id := Parent (Larray);
               begin
                  Larray :=
                    Unchecked_Convert_To
                      (Underlying_Type (Etype (Larray)), Larray);
                  Set_Parent (Larray, Par);
               end;
            end if;
         end if;

         if Nkind (Act_Rhs) = N_Slice then
            Rarray := Prefix (Act_Rhs);
         else
            Rarray := Act_Rhs;

            if Is_Private_Type (Etype (Rarray)) then
               declare
                  Par : constant Node_Id := Parent (Rarray);
               begin
                  Rarray :=
                    Unchecked_Convert_To
                      (Underlying_Type (Etype (Rarray)), Rarray);
                  Set_Parent (Rarray, Par);
               end;
            end if;
         end if;

         --  If both sides are slices, we must figure out whether it is safe
         --  to do the move in one direction or the other. It is always safe
         --  if there is a change of representation since obviously two arrays
         --  with different representations cannot possibly overlap.

         if (not Crep) and L_Slice and R_Slice then
            Act_L_Array := Get_Referenced_Object (Prefix (Act_Lhs));
            Act_R_Array := Get_Referenced_Object (Prefix (Act_Rhs));

            --  If both left- and right-hand arrays are entity names, and refer
            --  to different entities, then we know that the move is safe (the
            --  two storage areas are completely disjoint).

            if Is_Entity_Name (Act_L_Array)
              and then Is_Entity_Name (Act_R_Array)
              and then Entity (Act_L_Array) /= Entity (Act_R_Array)
            then
               null;

            --  Otherwise, we assume the worst, which is that the two arrays
            --  are the same array. There is no need to check if we know that
            --  is the case, because if we don't know it, we still have to
            --  assume it.

            --  Generally if the same array is involved, then we have an
            --  overlapping case. We will have to really assume the worst (i.e.
            --  set neither of the OK flags) unless we can determine the lower
            --  or upper bounds at compile time and compare them.

            else
               Cresult :=
                 Compile_Time_Compare
                   (Left_Lo, Right_Lo, Assume_Valid => True);

               if Cresult = Unknown then
                  Cresult :=
                    Compile_Time_Compare
                      (Left_Hi, Right_Hi, Assume_Valid => True);
               end if;

               case Cresult is
                  when EQ | LE | LT =>
                     Set_Backwards_OK (N, False);

                  when GE | GT =>
                     Set_Forwards_OK  (N, False);

                  when NE | Unknown =>
                     Set_Backwards_OK (N, False);
                     Set_Forwards_OK  (N, False);
               end case;
            end if;
         end if;

         --  If after that analysis Loop_Required is False, meaning that we
         --  have not discovered some non-overlap reason for requiring a loop,
         --  then the outcome depends on the capabilities of the back end.

         if not Loop_Required then
            --  Assume the back end can deal with all cases of overlap by
            --  falling back to memmove if it cannot use a more efficient
            --  approach.

            return;
         end if;

         --  At this stage we have to generate an explicit loop, and we have
         --  the following cases:

         --  Forwards_OK = True

         --    Rnn : right_index := right_index'First;
         --    for Lnn in left-index loop
         --       left (Lnn) := right (Rnn);
         --       Rnn := right_index'Succ (Rnn);
         --    end loop;

         --    Note: the above code MUST be analyzed with checks off, because
         --    otherwise the Succ could overflow. But in any case this is more
         --    efficient.

         --  Forwards_OK = False, Backwards_OK = True

         --    Rnn : right_index := right_index'Last;
         --    for Lnn in reverse left-index loop
         --       left (Lnn) := right (Rnn);
         --       Rnn := right_index'Pred (Rnn);
         --    end loop;

         --    Note: the above code MUST be analyzed with checks off, because
         --    otherwise the Pred could overflow. But in any case this is more
         --    efficient.

         --  Forwards_OK = Backwards_OK = False

         --    This only happens if we have the same array on each side. It is
         --    possible to create situations using overlays that violate this,
         --    but we simply do not promise to get this "right" in this case.

         --    There are two possible subcases. If the No_Implicit_Conditionals
         --    restriction is set, then we generate the following code:

         --      declare
         --        T : constant <operand-type> := rhs;
         --      begin
         --        lhs := T;
         --      end;

         --    If implicit conditionals are permitted, then we generate:

         --      if Left_Lo <= Right_Lo then
         --         <code for Forwards_OK = True above>
         --      else
         --         <code for Backwards_OK = True above>
         --      end if;

         --  In order to detect possible aliasing, we examine the renamed
         --  expression when the source or target is a renaming. However,
         --  the renaming may be intended to capture an address that may be
         --  affected by subsequent code, and therefore we must recover
         --  the actual entity for the expansion that follows, not the
         --  object it renames. In particular, if source or target designate
         --  a portion of a dynamically allocated object, the pointer to it
         --  may be reassigned but the renaming preserves the proper location.

         if Is_Entity_Name (Rhs)
           and then
             Nkind (Parent (Entity (Rhs))) = N_Object_Renaming_Declaration
           and then Nkind (Act_Rhs) = N_Slice
         then
            Rarray := Rhs;
         end if;

         if Is_Entity_Name (Lhs)
           and then
             Nkind (Parent (Entity (Lhs))) = N_Object_Renaming_Declaration
           and then Nkind (Act_Lhs) = N_Slice
         then
            Larray := Lhs;
         end if;

         --  Cases where either Forwards_OK or Backwards_OK is true

         if Forwards_OK (N) or else Backwards_OK (N) then
            if Needs_Finalization (Component_Type (L_Type))
              and then Base_Type (L_Type) = Base_Type (R_Type)
              and then Ndim = 1
              and then not No_Ctrl_Actions (N)
            then
               declare
                  Proc    : constant Entity_Id :=
                              TSS (Base_Type (L_Type), TSS_Slice_Assign);
                  Actuals : List_Id;

               begin
                  Apply_Dereference (Larray);
                  Apply_Dereference (Rarray);
                  Actuals := New_List (
                    Duplicate_Subexpr (Larray,   Name_Req => True),
                    Duplicate_Subexpr (Rarray,   Name_Req => True),
                    Duplicate_Subexpr (Left_Lo,  Name_Req => True),
                    Duplicate_Subexpr (Left_Hi,  Name_Req => True),
                    Duplicate_Subexpr (Right_Lo, Name_Req => True),
                    Duplicate_Subexpr (Right_Hi, Name_Req => True));

                  Append_To (Actuals,
                    New_Occurrence_Of (
                      Boolean_Literals (not Forwards_OK (N)), Loc));

                  Rewrite (N,
                    Make_Procedure_Call_Statement (Loc,
                      Name => New_Occurrence_Of (Proc, Loc),
                      Parameter_Associations => Actuals));
               end;

            else
               Rewrite (N,
                 Expand_Assign_Array_Loop_Or_Bitfield
                   (N, Larray, Rarray, L_Type, R_Type, Ndim,
                    Rev => not Forwards_OK (N)));
            end if;

         --  Case of both are false with No_Implicit_Conditionals

         elsif Restriction_Active (No_Implicit_Conditionals) then
            declare
                  T : constant Entity_Id :=
                        Make_Defining_Identifier (Loc, Chars => Name_T);

            begin
               Rewrite (N,
                 Make_Block_Statement (Loc,
                  Declarations => New_List (
                    Make_Object_Declaration (Loc,
                      Defining_Identifier => T,
                      Constant_Present  => True,
                      Object_Definition =>
                        New_Occurrence_Of (Etype (Rhs), Loc),
                      Expression        => Relocate_Node (Rhs))),

                    Handled_Statement_Sequence =>
                      Make_Handled_Sequence_Of_Statements (Loc,
                        Statements => New_List (
                          Make_Assignment_Statement (Loc,
                            Name       => Relocate_Node (Lhs),
                            Expression => New_Occurrence_Of (T, Loc))))));
            end;

         --  Case of both are false with implicit conditionals allowed

         else
            --  Before we generate this code, we must ensure that the left and
            --  right side array types are defined. They may be itypes, and we
            --  cannot let them be defined inside the if, since the first use
            --  in the then may not be executed.

            Ensure_Defined (L_Type, N);
            Ensure_Defined (R_Type, N);

            --  We normally compare addresses to find out which way round to
            --  do the loop, since this is reliable, and handles the cases of
            --  parameters, conversions etc. But we can't do that in the bit
            --  packed case, because addresses don't work there.

            if not Is_Bit_Packed_Array (L_Type) then
               Condition :=
                 Make_Op_Le (Loc,
                   Left_Opnd =>
                     Unchecked_Convert_To (RTE (RE_Integer_Address),
                       Make_Attribute_Reference (Loc,
                         Prefix =>
                           Make_Indexed_Component (Loc,
                             Prefix =>
                               Duplicate_Subexpr_Move_Checks (Larray, True),
                             Expressions => New_List (
                               Make_Attribute_Reference (Loc,
                                 Prefix =>
                                   New_Occurrence_Of
                                     (L_Index_Typ, Loc),
                                 Attribute_Name => Name_First))),
                         Attribute_Name => Name_Address)),

                   Right_Opnd =>
                     Unchecked_Convert_To (RTE (RE_Integer_Address),
                       Make_Attribute_Reference (Loc,
                         Prefix =>
                           Make_Indexed_Component (Loc,
                             Prefix =>
                               Duplicate_Subexpr_Move_Checks (Rarray, True),
                             Expressions => New_List (
                               Make_Attribute_Reference (Loc,
                                 Prefix =>
                                   New_Occurrence_Of
                                     (R_Index_Typ, Loc),
                                 Attribute_Name => Name_First))),
                         Attribute_Name => Name_Address)));

            --  For the bit packed and VM cases we use the bounds. That's OK,
            --  because we don't have to worry about parameters, since they
            --  cannot cause overlap. Perhaps we should worry about weird slice
            --  conversions ???

            else
               --  Copy the bounds

               Cleft_Lo  := New_Copy_Tree (Left_Lo);
               Cright_Lo := New_Copy_Tree (Right_Lo);

               --  If the types do not match we add an implicit conversion
               --  here to ensure proper match

               if Etype (Left_Lo) /= Etype (Right_Lo) then
                  Cright_Lo :=
                    Unchecked_Convert_To (Etype (Left_Lo), Cright_Lo);
               end if;

               --  Reset the Analyzed flag, because the bounds of the index
               --  type itself may be universal, and must be reanalyzed to
               --  acquire the proper type for the back end.

               Set_Analyzed (Cleft_Lo, False);
               Set_Analyzed (Cright_Lo, False);

               Condition :=
                 Make_Op_Le (Loc,
                   Left_Opnd  => Cleft_Lo,
                   Right_Opnd => Cright_Lo);
            end if;

            if Needs_Finalization (Component_Type (L_Type))
              and then Base_Type (L_Type) = Base_Type (R_Type)
              and then Ndim = 1
              and then not No_Ctrl_Actions (N)
            then

               --  Call TSS procedure for array assignment, passing the
               --  explicit bounds of right- and left-hand sides.

               declare
                  Proc    : constant Entity_Id :=
                              TSS (Base_Type (L_Type), TSS_Slice_Assign);
                  Actuals : List_Id;

               begin
                  Apply_Dereference (Larray);
                  Apply_Dereference (Rarray);
                  Actuals := New_List (
                    Duplicate_Subexpr (Larray,   Name_Req => True),
                    Duplicate_Subexpr (Rarray,   Name_Req => True),
                    Duplicate_Subexpr (Left_Lo,  Name_Req => True),
                    Duplicate_Subexpr (Left_Hi,  Name_Req => True),
                    Duplicate_Subexpr (Right_Lo, Name_Req => True),
                    Duplicate_Subexpr (Right_Hi, Name_Req => True));

                  Append_To (Actuals,
                     Make_Op_Not (Loc,
                       Right_Opnd => Condition));

                  Rewrite (N,
                    Make_Procedure_Call_Statement (Loc,
                      Name => New_Occurrence_Of (Proc, Loc),
                      Parameter_Associations => Actuals));
               end;

            else
               Rewrite (N,
                 Make_Implicit_If_Statement (N,
                   Condition => Condition,

                   Then_Statements => New_List (
                     Expand_Assign_Array_Loop_Or_Bitfield
                      (N, Larray, Rarray, L_Type, R_Type, Ndim,
                       Rev => False)),

                   Else_Statements => New_List (
                     Expand_Assign_Array_Loop_Or_Bitfield
                      (N, Larray, Rarray, L_Type, R_Type, Ndim,
                       Rev => True))));
            end if;
         end if;

         Analyze (N, Suppress => All_Checks);
      end;

   exception
      when RE_Not_Available =>
         return;
   end Expand_Assign_Array;

   ------------------------------
   -- Expand_Assign_Array_Loop --
   ------------------------------

   --  The following is an example of the loop generated for the case of a
   --  two-dimensional array:

   --    declare
   --       R2b : Tm1X1 := 1;
   --    begin
   --       for L1b in 1 .. 100 loop
   --          declare
   --             R4b : Tm1X2 := 1;
   --          begin
   --             for L3b in 1 .. 100 loop
   --                vm1 (L1b, L3b) := vm2 (R2b, R4b);
   --                R4b := Tm1X2'succ(R4b);
   --             end loop;
   --          end;
   --          R2b := Tm1X1'succ(R2b);
   --       end loop;
   --    end;

   --  Here Rev is False, and Tm1Xn are the subscript types for the right-hand
   --  side. The declarations of R2b and R4b are inserted before the original
   --  assignment statement.

   function Expand_Assign_Array_Loop
     (N      : Node_Id;
      Larray : Entity_Id;
      Rarray : Entity_Id;
      L_Type : Entity_Id;
      R_Type : Entity_Id;
      Ndim   : Pos;
      Rev    : Boolean) return Node_Id
   is
      Loc  : constant Source_Ptr := Sloc (N);

      Lnn : array (1 .. Ndim) of Entity_Id;
      Rnn : array (1 .. Ndim) of Entity_Id;
      --  Entities used as subscripts on left and right sides

      L_Index_Type : array (1 .. Ndim) of Entity_Id;
      R_Index_Type : array (1 .. Ndim) of Entity_Id;
      --  Left and right index types

      Assign : Node_Id;

      F_Or_L : Name_Id;
      S_Or_P : Name_Id;

      function Build_Step (J : Nat) return Node_Id;
      --  The increment step for the index of the right-hand side is written
      --  as an attribute reference (Succ or Pred). This function returns
      --  the corresponding node, which is placed at the end of the loop body.

      ----------------
      -- Build_Step --
      ----------------

      function Build_Step (J : Nat) return Node_Id is
         Step : Node_Id;
         Lim  : Name_Id;

      begin
         if Rev then
            Lim := Name_First;
         else
            Lim := Name_Last;
         end if;

         Step :=
            Make_Assignment_Statement (Loc,
               Name => New_Occurrence_Of (Rnn (J), Loc),
               Expression =>
                 Make_Attribute_Reference (Loc,
                   Prefix =>
                     New_Occurrence_Of (R_Index_Type (J), Loc),
                   Attribute_Name => S_Or_P,
                   Expressions => New_List (
                     New_Occurrence_Of (Rnn (J), Loc))));

      --  Note that on the last iteration of the loop, the index is increased
      --  (or decreased) past the corresponding bound. This is consistent with
      --  the C semantics of the back-end, where such an off-by-one value on a
      --  dead index variable is OK. However, in CodePeer mode this leads to
      --  spurious warnings, and thus we place a guard around the attribute
      --  reference. For obvious reasons we only do this for CodePeer.

         if CodePeer_Mode then
            Step :=
              Make_If_Statement (Loc,
                 Condition =>
                    Make_Op_Ne (Loc,
                       Left_Opnd  => New_Occurrence_Of (Lnn (J), Loc),
                       Right_Opnd =>
                         Make_Attribute_Reference (Loc,
                           Prefix => New_Occurrence_Of (L_Index_Type (J), Loc),
                           Attribute_Name => Lim)),
                 Then_Statements => New_List (Step));
         end if;

         return Step;
      end Build_Step;

   --  Start of processing for Expand_Assign_Array_Loop

   begin
      if Rev then
         F_Or_L := Name_Last;
         S_Or_P := Name_Pred;
      else
         F_Or_L := Name_First;
         S_Or_P := Name_Succ;
      end if;

      --  Setup index types and subscript entities

      declare
         L_Index : Node_Id;
         R_Index : Node_Id;

      begin
         L_Index := First_Index (L_Type);
         R_Index := First_Index (R_Type);

         for J in 1 .. Ndim loop
            Lnn (J) := Make_Temporary (Loc, 'L');
            Rnn (J) := Make_Temporary (Loc, 'R');

            L_Index_Type (J) := Etype (L_Index);
            R_Index_Type (J) := Etype (R_Index);

            Next_Index (L_Index);
            Next_Index (R_Index);
         end loop;
      end;

      --  Now construct the assignment statement

      declare
         ExprL : constant List_Id := New_List;
         ExprR : constant List_Id := New_List;

      begin
         for J in 1 .. Ndim loop
            Append_To (ExprL, New_Occurrence_Of (Lnn (J), Loc));
            Append_To (ExprR, New_Occurrence_Of (Rnn (J), Loc));
         end loop;

         Assign :=
           Make_Assignment_Statement (Loc,
             Name =>
               Make_Indexed_Component (Loc,
                 Prefix      => Duplicate_Subexpr (Larray, Name_Req => True),
                 Expressions => ExprL),
             Expression =>
               Make_Indexed_Component (Loc,
                 Prefix      => Duplicate_Subexpr (Rarray, Name_Req => True),
                 Expressions => ExprR));

         --  We set assignment OK, since there are some cases, e.g. in object
         --  declarations, where we are actually assigning into a constant.
         --  If there really is an illegality, it was caught long before now,
         --  and was flagged when the original assignment was analyzed.

         Set_Assignment_OK (Name (Assign));

         --  Propagate the No_Ctrl_Actions flag to individual assignments

         Set_No_Ctrl_Actions (Assign, No_Ctrl_Actions (N));
      end;

      --  Now construct the loop from the inside out, with the last subscript
      --  varying most rapidly. Note that Assign is first the raw assignment
      --  statement, and then subsequently the loop that wraps it up.

      for J in reverse 1 .. Ndim loop
         Assign :=
           Make_Block_Statement (Loc,
             Declarations => New_List (
              Make_Object_Declaration (Loc,
                Defining_Identifier => Rnn (J),
                Object_Definition =>
                  New_Occurrence_Of (R_Index_Type (J), Loc),
                Expression =>
                  Make_Attribute_Reference (Loc,
                    Prefix => New_Occurrence_Of (R_Index_Type (J), Loc),
                    Attribute_Name => F_Or_L))),

           Handled_Statement_Sequence =>
             Make_Handled_Sequence_Of_Statements (Loc,
               Statements => New_List (
                 Make_Implicit_Loop_Statement (N,
                   Iteration_Scheme =>
                     Make_Iteration_Scheme (Loc,
                       Loop_Parameter_Specification =>
                         Make_Loop_Parameter_Specification (Loc,
                           Defining_Identifier => Lnn (J),
                           Reverse_Present => Rev,
                           Discrete_Subtype_Definition =>
                             New_Occurrence_Of (L_Index_Type (J), Loc))),

                   Statements => New_List (Assign, Build_Step (J))))));
      end loop;

      return Assign;
   end Expand_Assign_Array_Loop;

   ----------------------------------
   -- Expand_Assign_Array_Bitfield --
   ----------------------------------

   function Expand_Assign_Array_Bitfield
     (N      : Node_Id;
      Larray : Entity_Id;
      Rarray : Entity_Id;
      L_Type : Entity_Id;
      R_Type : Entity_Id;
      Rev    : Boolean) return Node_Id
   is
      pragma Assert (not Rev);
      --  Reverse copying is not yet supported by Copy_Bitfield.

      pragma Assert (not Change_Of_Representation (N));
      --  This won't work, for example, to copy a packed array to an unpacked
      --  array.

      Loc  : constant Source_Ptr := Sloc (N);

      L_Index_Typ : constant Entity_Id := Etype (First_Index (L_Type));
      R_Index_Typ : constant Entity_Id := Etype (First_Index (R_Type));
      Left_Lo  : constant Node_Id := Type_Low_Bound  (L_Index_Typ);
      Right_Lo : constant Node_Id := Type_Low_Bound  (R_Index_Typ);

      L_Addr : constant Node_Id :=
        Make_Attribute_Reference (Loc,
          Prefix =>
            Make_Indexed_Component (Loc,
              Prefix =>
                Duplicate_Subexpr (Larray, True),
              Expressions => New_List (New_Copy_Tree (Left_Lo))),
          Attribute_Name => Name_Address);

      L_Bit : constant Node_Id :=
        Make_Attribute_Reference (Loc,
          Prefix =>
            Make_Indexed_Component (Loc,
              Prefix =>
                Duplicate_Subexpr (Larray, True),
              Expressions => New_List (New_Copy_Tree (Left_Lo))),
          Attribute_Name => Name_Bit);

      R_Addr : constant Node_Id :=
        Make_Attribute_Reference (Loc,
          Prefix =>
            Make_Indexed_Component (Loc,
              Prefix =>
                Duplicate_Subexpr (Rarray, True),
              Expressions => New_List (New_Copy_Tree (Right_Lo))),
          Attribute_Name => Name_Address);

      R_Bit : constant Node_Id :=
        Make_Attribute_Reference (Loc,
          Prefix =>
            Make_Indexed_Component (Loc,
              Prefix =>
                Duplicate_Subexpr (Rarray, True),
              Expressions => New_List (New_Copy_Tree (Right_Lo))),
          Attribute_Name => Name_Bit);

      --  Compute the Size of the bitfield

      --  Note that the length check has already been done, so we can use the
      --  size of either L or R; they are equal. We can't use 'Size here,
      --  because sometimes bit fields get copied into a temp, and the 'Size
      --  ends up being the size of the temp (e.g. an 8-bit temp containing
      --  a 4-bit bit field).

      Size : constant Node_Id :=
        Make_Op_Multiply (Loc,
          Make_Attribute_Reference (Loc,
            Prefix =>
              Duplicate_Subexpr (Name (N), True),
            Attribute_Name => Name_Length),
          Make_Attribute_Reference (Loc,
            Prefix =>
              Duplicate_Subexpr (Name (N), True),
            Attribute_Name => Name_Component_Size));

   begin
      return Make_Procedure_Call_Statement (Loc,
        Name => New_Occurrence_Of (RTE (RE_Copy_Bitfield), Loc),
        Parameter_Associations => New_List (
          R_Addr, R_Bit, L_Addr, L_Bit, Size));
   end Expand_Assign_Array_Bitfield;

   ---------------------------------------
   -- Expand_Assign_Array_Bitfield_Fast --
   ---------------------------------------

   function Expand_Assign_Array_Bitfield_Fast
     (N      : Node_Id;
      Larray : Entity_Id;
      Rarray : Entity_Id) return Node_Id
   is
      pragma Assert (not Change_Of_Representation (N));
      --  This won't work, for example, to copy a packed array to an unpacked
      --  array.

      --  For L (A .. B) := R (C .. D), we generate:
      --
      --     L := Fast_Copy_Bitfield (R, <offset of R(C)>, L, <offset of L(A)>,
      --                              L (A .. B)'Length * L'Component_Size);
      --
      --  with L and R suitably uncheckedly converted to/from Val_2.
      --  The offsets are from the start of L and R.

      Loc  : constant Source_Ptr := Sloc (N);

      L_Typ : constant Entity_Id := Etype (Larray);
      R_Typ : constant Entity_Id := Etype (Rarray);
      --  The original type of the arrays

      L_Val : constant Node_Id :=
        Unchecked_Convert_To (RTE (RE_Val_2), Larray);
      R_Val : constant Node_Id :=
        Unchecked_Convert_To (RTE (RE_Val_2), Rarray);
      --  Converted values of left- and right-hand sides

      L_Small : constant Boolean :=
        Known_Static_RM_Size (L_Typ)
          and then RM_Size (L_Typ) < Standard_Long_Long_Integer_Size;
      R_Small : constant Boolean :=
        Known_Static_RM_Size (R_Typ)
          and then RM_Size (R_Typ) < Standard_Long_Long_Integer_Size;
      --  Whether the above unchecked conversions need to be padded with zeros

      C_Size : constant Uint := Component_Size (L_Typ);
      pragma Assert (C_Size >= 1);
      pragma Assert (C_Size = Component_Size (R_Typ));

      Larray_Bounds : constant Range_Values :=
        Get_Index_Bounds (First_Index (L_Typ));
      L_Bounds : constant Range_Values :=
        (if Nkind (Name (N)) = N_Slice
         then Get_Index_Bounds (Discrete_Range (Name (N)))
         else Larray_Bounds);
      --  If the left-hand side is A (First..Last), Larray_Bounds is A'Range,
      --  and L_Bounds is First..Last. If it's not a slice, we treat it like
      --  a slice starting at A'First.

      L_Bit : constant Node_Id :=
        Make_Integer_Literal
          (Loc, (L_Bounds.First - Larray_Bounds.First) * C_Size);

      Rarray_Bounds : constant Range_Values :=
        Get_Index_Bounds (First_Index (R_Typ));
      R_Bounds : constant Range_Values :=
        (if Nkind (Expression (N)) = N_Slice
         then Get_Index_Bounds (Discrete_Range (Expression (N)))
         else Rarray_Bounds);

      R_Bit : constant Node_Id :=
        Make_Integer_Literal
          (Loc, (R_Bounds.First - Rarray_Bounds.First) * C_Size);

      Size : constant Node_Id :=
        Make_Op_Multiply (Loc,
          Make_Attribute_Reference (Loc,
            Prefix =>
              Duplicate_Subexpr (Name (N), True),
            Attribute_Name => Name_Length),
          Make_Attribute_Reference (Loc,
            Prefix =>
              Duplicate_Subexpr (Larray, True),
            Attribute_Name => Name_Component_Size));

      L_Arg, R_Arg, Call : Node_Id;

   begin
      --  The semantics of unchecked conversion between bit-packed arrays that
      --  are implemented as modular types and modular types is precisely that
      --  of unchecked conversion between modular types. Therefore, if it needs
      --  to be padded with zeros, the padding must be moved to the correct end
      --  for memory order because System.Bitfield_Utils works in memory order.

      if L_Small
        and then (Bytes_Big_Endian xor Reverse_Storage_Order (L_Typ))
      then
         L_Arg := Make_Op_Shift_Left (Loc,
           Left_Opnd  => L_Val,
           Right_Opnd => Make_Integer_Literal (Loc,
                           Standard_Long_Long_Integer_Size - RM_Size (L_Typ)));
      else
         L_Arg := L_Val;
      end if;

      if R_Small
        and then (Bytes_Big_Endian xor Reverse_Storage_Order (R_Typ))
      then
         R_Arg := Make_Op_Shift_Left (Loc,
           Left_Opnd  => R_Val,
           Right_Opnd => Make_Integer_Literal (Loc,
                           Standard_Long_Long_Integer_Size - RM_Size (R_Typ)));
      else
         R_Arg := R_Val;
      end if;

      Call := Make_Function_Call (Loc,
        Name => New_Occurrence_Of (RTE (RE_Fast_Copy_Bitfield), Loc),
        Parameter_Associations => New_List (
          R_Arg, R_Bit, L_Arg, L_Bit, Size));

      --  Conversely, the final unchecked conversion must take significant bits

      if L_Small
        and then (Bytes_Big_Endian xor Reverse_Storage_Order (L_Typ))
      then
         Call := Make_Op_Shift_Right (Loc,
           Left_Opnd  => Call,
           Right_Opnd => Make_Integer_Literal (Loc,
                           Standard_Long_Long_Integer_Size - RM_Size (L_Typ)));
      end if;

      return Make_Assignment_Statement (Loc,
        Name => Duplicate_Subexpr (Larray, True),
        Expression => Unchecked_Convert_To (L_Typ, Call));
   end Expand_Assign_Array_Bitfield_Fast;

   ------------------------------------------
   -- Expand_Assign_Array_Loop_Or_Bitfield --
   ------------------------------------------

   function Expand_Assign_Array_Loop_Or_Bitfield
     (N      : Node_Id;
      Larray : Entity_Id;
      Rarray : Entity_Id;
      L_Type : Entity_Id;
      R_Type : Entity_Id;
      Ndim   : Pos;
      Rev    : Boolean) return Node_Id
   is

      L : constant Node_Id := Name (N);
      R : constant Node_Id := Expression (N);
      --  Left- and right-hand sides of the assignment statement

      Slices : constant Boolean :=
        Nkind (L) = N_Slice or else Nkind (R) = N_Slice;
      L_Prefix_Comp : constant Boolean :=
        --  True if the left-hand side is a slice of a component or slice
        Nkind (L) = N_Slice
          and then Nkind (Prefix (L)) in
                     N_Selected_Component | N_Indexed_Component | N_Slice;
      R_Prefix_Comp : constant Boolean :=
        --  Likewise for the right-hand side
        Nkind (R) = N_Slice
          and then Nkind (Prefix (R)) in
                     N_Selected_Component | N_Indexed_Component | N_Slice;

   begin
      --  Determine whether Copy_Bitfield or Fast_Copy_Bitfield is appropriate
      --  (will work, and will be more efficient than component-by-component
      --  copy). Copy_Bitfield doesn't work for reversed storage orders. It is
      --  efficient for slices of bit-packed arrays. Copy_Bitfield can read and
      --  write bits that are not part of the objects being copied, so we don't
      --  want to use it if there are volatile or independent components. If
      --  the Prefix of the slice is a component or slice, then it might be a
      --  part of an object with some other volatile or independent components,
      --  so we disable the optimization in that case as well. We could
      --  complicate this code by actually looking for such volatile and
      --  independent components.

      if Is_Bit_Packed_Array (L_Type)
        and then Is_Bit_Packed_Array (R_Type)
        and then not Reverse_Storage_Order (L_Type)
        and then not Reverse_Storage_Order (R_Type)
        and then Ndim = 1
        and then Slices
        and then not Has_Volatile_Component (L_Type)
        and then not Has_Volatile_Component (R_Type)
        and then not Has_Independent_Components (L_Type)
        and then not Has_Independent_Components (R_Type)
        and then not L_Prefix_Comp
        and then not R_Prefix_Comp
      then
         --  Here if Copy_Bitfield can work (except for the Rev test below).
         --  Determine whether to call Fast_Copy_Bitfield instead. If we
         --  are assigning slices, and all the relevant bounds are known at
         --  compile time, and the maximum object size is no greater than
         --  System.Bitfields.Val_Bits (i.e. Long_Long_Integer'Size / 2), and
         --  we don't have enumeration representation clauses, we can use
         --  Fast_Copy_Bitfield. The max size test is to ensure that the slices
         --  cannot overlap boundaries not supported by Fast_Copy_Bitfield.

         pragma Assert (Known_Component_Size (Base_Type (L_Type)));
         pragma Assert (Known_Component_Size (Base_Type (R_Type)));

         --  Note that L_Type and R_Type do not necessarily have the same base
         --  type, because of array type conversions. Hence the need to check
         --  various properties of both.

         if Compile_Time_Known_Bounds (Base_Type (L_Type))
           and then Compile_Time_Known_Bounds (Base_Type (R_Type))
         then
            declare
               Left_Base_Index : constant Entity_Id :=
                 First_Index (Base_Type (L_Type));
               Left_Base_Range : constant Range_Values :=
                 Get_Index_Bounds (Left_Base_Index);

               Right_Base_Index : constant Entity_Id :=
                 First_Index (Base_Type (R_Type));
               Right_Base_Range : constant Range_Values :=
                 Get_Index_Bounds (Right_Base_Index);

               Known_Left_Slice_Low : constant Boolean :=
                 (if Nkind (L) = N_Slice
                    then Compile_Time_Known_Value
                      (Get_Index_Bounds (Discrete_Range (L)).First));
               Known_Right_Slice_Low : constant Boolean :=
                 (if Nkind (R) = N_Slice
                    then Compile_Time_Known_Value
                      (Get_Index_Bounds (Discrete_Range (R)).Last));

               Val_Bits : constant Pos := Standard_Long_Long_Integer_Size / 2;

            begin
               if Left_Base_Range.Last - Left_Base_Range.First < Val_Bits
                 and then Right_Base_Range.Last - Right_Base_Range.First <
                            Val_Bits
                 and then Known_Esize (L_Type)
                 and then Known_Esize (R_Type)
                 and then Known_Left_Slice_Low
                 and then Known_Right_Slice_Low
                 and then Compile_Time_Known_Value
                   (Get_Index_Bounds (First_Index (Etype (Larray))).First)
                 and then Compile_Time_Known_Value
                   (Get_Index_Bounds (First_Index (Etype (Rarray))).First)
                 and then
                   not (Is_Enumeration_Type (Etype (Left_Base_Index))
                          and then Has_Enumeration_Rep_Clause
                            (Etype (Left_Base_Index)))
                 and then RTE_Available (RE_Fast_Copy_Bitfield)
               then
                  pragma Assert (Known_Esize (L_Type));
                  pragma Assert (Known_Esize (R_Type));

                  return Expand_Assign_Array_Bitfield_Fast (N, Larray, Rarray);
               end if;
            end;
         end if;

         --  Fast_Copy_Bitfield can work if Rev is True, because the data is
         --  passed and returned by copy. Copy_Bitfield cannot.

         if not Rev and then RTE_Available (RE_Copy_Bitfield) then
            return Expand_Assign_Array_Bitfield
              (N, Larray, Rarray, L_Type, R_Type, Rev);
         end if;
      end if;

      --  Here if we did not return above, with Fast_Copy_Bitfield or
      --  Copy_Bitfield.

      return Expand_Assign_Array_Loop
        (N, Larray, Rarray, L_Type, R_Type, Ndim, Rev);
   end Expand_Assign_Array_Loop_Or_Bitfield;

   --------------------------
   -- Expand_Assign_Record --
   --------------------------

   procedure Expand_Assign_Record (N : Node_Id) is
      Lhs   : constant Node_Id    := Name (N);
      Rhs   : Node_Id             := Expression (N);
      L_Typ : constant Entity_Id  := Base_Type (Etype (Lhs));

   begin
      --  If change of representation, then extract the real right-hand side
      --  from the type conversion, and proceed with component-wise assignment,
      --  since the two types are not the same as far as the back end is
      --  concerned.

      if Change_Of_Representation (N) then
         Rhs := Expression (Rhs);

      --  If this may be a case of a large bit aligned component, then proceed
      --  with component-wise assignment, to avoid possible clobbering of other
      --  components sharing bits in the first or last byte of the component to
      --  be assigned.

      elsif Possible_Bit_Aligned_Component (Lhs)
              or else
            Possible_Bit_Aligned_Component (Rhs)
      then
         null;

      --  If we have a tagged type that has a complete record representation
      --  clause, we must do we must do component-wise assignments, since child
      --  types may have used gaps for their components, and we might be
      --  dealing with a view conversion.

      elsif Is_Fully_Repped_Tagged_Type (L_Typ) then
         null;

      --  If neither condition met, then nothing special to do, the back end
      --  can handle assignment of the entire component as a single entity.

      else
         return;
      end if;

      --  At this stage we know that we must do a component wise assignment

      declare
         Loc   : constant Source_Ptr := Sloc (N);
         R_Typ : constant Entity_Id  := Base_Type (Etype (Rhs));
         Decl  : constant Node_Id    := Declaration_Node (R_Typ);
         RDef  : Node_Id;
         F     : Entity_Id;

         function Find_Component
           (Typ  : Entity_Id;
            Comp : Entity_Id) return Entity_Id;
         --  Find the component with the given name in the underlying record
         --  declaration for Typ. We need to use the actual entity because the
         --  type may be private and resolution by identifier alone would fail.

         function Make_Component_List_Assign
           (CL  : Node_Id;
            U_U : Boolean := False) return List_Id;
         --  Returns a sequence of statements to assign the components that
         --  are referenced in the given component list. The flag U_U is
         --  used to force the usage of the inferred value of the variant
         --  part expression as the switch for the generated case statement.

         function Make_Field_Assign
           (C   : Entity_Id;
            U_U : Boolean := False) return Node_Id;
         --  Given C, the entity for a discriminant or component, build an
         --  assignment for the corresponding field values. The flag U_U
         --  signals the presence of an Unchecked_Union and forces the usage
         --  of the inferred discriminant value of C as the right-hand side
         --  of the assignment.

         function Make_Field_Assigns (CI : List_Id) return List_Id;
         --  Given CI, a component items list, construct series of statements
         --  for fieldwise assignment of the corresponding components.

         --------------------
         -- Find_Component --
         --------------------

         function Find_Component
           (Typ  : Entity_Id;
            Comp : Entity_Id) return Entity_Id
         is
            Utyp : constant Entity_Id := Underlying_Type (Typ);
            C    : Entity_Id;

         begin
            C := First_Entity (Utyp);
            while Present (C) loop
               if Chars (C) = Chars (Comp) then
                  return C;

               --  The component may be a renamed discriminant, in
               --  which case check against the name of the original
               --  discriminant of the parent type.

               elsif Is_Derived_Type (Scope (Comp))
                 and then Ekind (Comp) = E_Discriminant
                 and then Present (Corresponding_Discriminant (Comp))
                 and then
                   Chars (C) = Chars (Corresponding_Discriminant (Comp))
               then
                  return C;
               end if;

               Next_Entity (C);
            end loop;

            raise Program_Error;
         end Find_Component;

         --------------------------------
         -- Make_Component_List_Assign --
         --------------------------------

         function Make_Component_List_Assign
           (CL  : Node_Id;
            U_U : Boolean := False) return List_Id
         is
            CI : constant List_Id := Component_Items (CL);
            VP : constant Node_Id := Variant_Part (CL);

            Constrained_Typ : Entity_Id;
            Alts            : List_Id;
            DC              : Node_Id;
            DCH             : List_Id;
            Expr            : Node_Id;
            Result          : List_Id;
            V               : Node_Id;

         begin
            --  Try to find a constrained type to extract discriminant values
            --  from, so that the case statement built below gets an
            --  opportunity to be folded by Expand_N_Case_Statement.

            if U_U or else Is_Constrained (Etype (Rhs)) then
               Constrained_Typ := Etype (Rhs);
            elsif Is_Constrained (Etype (Expression (N))) then
               Constrained_Typ := Etype (Expression (N));
            else
               Constrained_Typ := Empty;
            end if;

            Result := Make_Field_Assigns (CI);

            if Present (VP) then
               V := First_Non_Pragma (Variants (VP));
               Alts := New_List;
               while Present (V) loop
                  DCH := New_List;
                  DC := First (Discrete_Choices (V));
                  while Present (DC) loop
                     Append_To (DCH, New_Copy_Tree (DC));
                     Next (DC);
                  end loop;

                  Append_To (Alts,
                    Make_Case_Statement_Alternative (Loc,
                      Discrete_Choices => DCH,
                      Statements =>
                        Make_Component_List_Assign (Component_List (V))));
                  Next_Non_Pragma (V);
               end loop;

               if Present (Constrained_Typ) then
                  Expr :=
                    New_Copy (Get_Discriminant_Value (
                      Entity (Name (VP)),
                      Constrained_Typ,
                      Discriminant_Constraint (Constrained_Typ)));
               else
                  Expr :=
                    Make_Selected_Component (Loc,
                      Prefix        => Duplicate_Subexpr (Rhs),
                      Selector_Name =>
                        Make_Identifier (Loc, Chars (Name (VP))));
               end if;

               Append_To (Result,
                 Make_Case_Statement (Loc,
                   Expression => Expr,
                   Alternatives => Alts));
            end if;

            return Result;
         end Make_Component_List_Assign;

         -----------------------
         -- Make_Field_Assign --
         -----------------------

         function Make_Field_Assign
           (C   : Entity_Id;
            U_U : Boolean := False) return Node_Id
         is
            A    : Node_Id;
            Disc : Entity_Id;
            Expr : Node_Id;

         begin
            --  The discriminant entity to be used in the retrieval below must
            --  be one in the corresponding type, given that the assignment may
            --  be between derived and parent types.

            if Is_Derived_Type (Etype (Rhs)) then
               Disc := Find_Component (R_Typ, C);
            else
               Disc := C;
            end if;

            --  In the case of an Unchecked_Union, use the discriminant
            --  constraint value as on the right-hand side of the assignment.

            if U_U then
               Expr :=
                 New_Copy (Get_Discriminant_Value (C,
                   Etype (Rhs),
                   Discriminant_Constraint (Etype (Rhs))));
            else
               Expr :=
                 Make_Selected_Component (Loc,
                   Prefix        => Duplicate_Subexpr (Rhs),
                   Selector_Name => New_Occurrence_Of (Disc, Loc));
            end if;

            --  Generate the assignment statement. When the left-hand side
            --  is an object with an address clause present, force generated
            --  temporaries to be renamings so as to correctly assign to any
            --  overlaid objects.

            A :=
              Make_Assignment_Statement (Loc,
                Name       =>
                  Make_Selected_Component (Loc,
                    Prefix        =>
                      Duplicate_Subexpr
                        (Exp          => Lhs,
                         Name_Req     => False,
                         Renaming_Req =>
                           Is_Entity_Name (Lhs)
                             and then Present (Address_Clause (Entity (Lhs)))),
                    Selector_Name =>
                      New_Occurrence_Of (Find_Component (L_Typ, C), Loc)),
                Expression => Expr);

            --  Set Assignment_OK, so discriminants can be assigned

            Set_Assignment_OK (Name (A), True);

            if Componentwise_Assignment (N)
              and then Nkind (Name (A)) = N_Selected_Component
              and then Chars (Selector_Name (Name (A))) = Name_uParent
            then
               Set_Componentwise_Assignment (A);
            end if;

            return A;
         end Make_Field_Assign;

         ------------------------
         -- Make_Field_Assigns --
         ------------------------

         function Make_Field_Assigns (CI : List_Id) return List_Id is
            Item   : Node_Id;
            Result : List_Id;

         begin
            Item := First (CI);
            Result := New_List;

            while Present (Item) loop

               --  Look for components, but exclude _tag field assignment if
               --  the special Componentwise_Assignment flag is set.

               if Nkind (Item) = N_Component_Declaration
                 and then not (Is_Tag (Defining_Identifier (Item))
                                 and then Componentwise_Assignment (N))
               then
                  Append_To
                    (Result, Make_Field_Assign (Defining_Identifier (Item)));
               end if;

               Next (Item);
            end loop;

            return Result;
         end Make_Field_Assigns;

      --  Start of processing for Expand_Assign_Record

      begin
         --  Note that we need to use the base types for this processing in
         --  order to retrieve the Type_Definition. In the constrained case,
         --  we filter out the non relevant fields in
         --  Make_Component_List_Assign.

         --  First copy the discriminants. This is done unconditionally. It
         --  is required in the unconstrained left side case, and also in the
         --  case where this assignment was constructed during the expansion
         --  of a type conversion (since initialization of discriminants is
         --  suppressed in this case). It is unnecessary but harmless in
         --  other cases.

         --  Special case: no copy if the target has no discriminants

         if Has_Discriminants (L_Typ)
           and then Is_Unchecked_Union (Base_Type (L_Typ))
         then
            null;

         elsif Has_Discriminants (L_Typ) then
            F := First_Discriminant (R_Typ);
            while Present (F) loop

               --  If we are expanding the initialization of a derived record
               --  that constrains or renames discriminants of the parent, we
               --  must use the corresponding discriminant in the parent.

               declare
                  CF : Entity_Id;

               begin
                  if Inside_Init_Proc
                    and then Present (Corresponding_Discriminant (F))
                  then
                     CF := Corresponding_Discriminant (F);
                  else
                     CF := F;
                  end if;

                  if Is_Unchecked_Union (R_Typ) then

                     --  Within an initialization procedure this is the
                     --  assignment to an unchecked union component, in which
                     --  case there is no discriminant to initialize.

                     if Inside_Init_Proc then
                        null;

                     else
                        --  The assignment is part of a conversion from a
                        --  derived unchecked union type with an inferable
                        --  discriminant, to a parent type.

                        Insert_Action (N, Make_Field_Assign (CF, True));
                     end if;

                  else
                     Insert_Action (N, Make_Field_Assign (CF));
                  end if;

                  Next_Discriminant (F);
               end;
            end loop;

            --  If the derived type has a stored constraint, assign the value
            --  of the corresponding discriminants explicitly, skipping those
            --  that are renamed discriminants. We cannot just retrieve them
            --  from the Rhs by selected component because they are invisible
            --  in the type of the right-hand side.

            if Stored_Constraint (R_Typ) /= No_Elist then
               declare
                  Assign    : Node_Id;
                  Discr_Val : Elmt_Id;

               begin
                  Discr_Val := First_Elmt (Stored_Constraint (R_Typ));
                  F := First_Entity (R_Typ);
                  while Present (F) loop
                     if Ekind (F) = E_Discriminant
                       and then Is_Completely_Hidden (F)
                       and then Present (Corresponding_Record_Component (F))
                       and then
                         (not Is_Entity_Name (Node (Discr_Val))
                           or else Ekind (Entity (Node (Discr_Val))) /=
                                     E_Discriminant)
                     then
                        Assign :=
                          Make_Assignment_Statement (Loc,
                            Name       =>
                              Make_Selected_Component (Loc,
                                Prefix        => Duplicate_Subexpr (Lhs),
                                Selector_Name =>
                                  New_Occurrence_Of
                                    (Corresponding_Record_Component (F), Loc)),
                            Expression => New_Copy (Node (Discr_Val)));

                        Set_Assignment_OK (Name (Assign));
                        Insert_Action (N, Assign);
                        Next_Elmt (Discr_Val);
                     end if;

                     Next_Entity (F);
                  end loop;
               end;
            end if;
         end if;

         --  We know the underlying type is a record, but its current view
         --  may be private. We must retrieve the usable record declaration.

         if Nkind (Decl) in N_Private_Type_Declaration
                          | N_Private_Extension_Declaration
           and then Present (Full_View (R_Typ))
         then
            RDef := Type_Definition (Declaration_Node (Full_View (R_Typ)));
         else
            RDef := Type_Definition (Decl);
         end if;

         if Nkind (RDef) = N_Derived_Type_Definition then
            RDef := Record_Extension_Part (RDef);
         end if;

         if Nkind (RDef) = N_Record_Definition
           and then Present (Component_List (RDef))
         then
            if Is_Unchecked_Union (R_Typ) then
               Insert_Actions (N,
                 Make_Component_List_Assign (Component_List (RDef), True));
            else
               Insert_Actions (N,
                 Make_Component_List_Assign (Component_List (RDef)));
            end if;

            Rewrite (N, Make_Null_Statement (Loc));
         end if;
      end;
   end Expand_Assign_Record;

   -------------------------------------
   -- Expand_Assign_With_Target_Names --
   -------------------------------------

   procedure Expand_Assign_With_Target_Names (N : Node_Id) is
      LHS     : constant Node_Id    := Name (N);
      LHS_Typ : constant Entity_Id  := Etype (LHS);
      Loc     : constant Source_Ptr := Sloc (N);
      RHS     : constant Node_Id    := Expression (N);

      Ent : Entity_Id;
      --  The entity of the left-hand side

      function Replace_Target (N : Node_Id) return Traverse_Result;
      --  Replace occurrences of the target name by the proper entity: either
      --  the entity of the LHS in simple cases, or the formal of the
      --  constructed procedure otherwise.

      --------------------
      -- Replace_Target --
      --------------------

      function Replace_Target (N : Node_Id) return Traverse_Result is
      begin
         if Nkind (N) = N_Target_Name then
            Rewrite (N, New_Occurrence_Of (Ent, Sloc (N)));

         --  The expression will be reanalyzed when the enclosing assignment
         --  is reanalyzed, so reset the entity, which may be a temporary
         --  created during analysis, e.g. a loop variable for an iterated
         --  component association. However, if entity is callable then
         --  resolution has established its proper identity (including in
         --  rewritten prefixed calls) so we must preserve it.

         elsif Is_Entity_Name (N) then
            if Present (Entity (N))
              and then not Is_Overloadable (Entity (N))
            then
               Set_Entity (N, Empty);
            end if;
         end if;

         Set_Analyzed (N, False);
         return OK;
      end Replace_Target;

      procedure Replace_Target_Name is new Traverse_Proc (Replace_Target);

      --  Local variables

      New_RHS : Node_Id;
      Proc_Id : Entity_Id;

   --  Start of processing for Expand_Assign_With_Target_Names

   begin
      New_RHS := New_Copy_Tree (RHS);

      --  The left-hand side is a direct name

      if Is_Entity_Name (LHS)
        and then not Is_Renaming_Of_Object (Entity (LHS))
      then
         Ent := Entity (LHS);
         Replace_Target_Name (New_RHS);

         --  Generate:
         --    LHS := ... LHS ...;

         Rewrite (N,
           Make_Assignment_Statement (Loc,
             Name       => Relocate_Node (LHS),
             Expression => New_RHS));

      --  The left-hand side is not a direct name, but is side-effect free.
      --  Capture its value in a temporary to avoid multiple evaluations.

      elsif Side_Effect_Free (LHS) then
         Ent := Make_Temporary (Loc, 'T');
         Replace_Target_Name (New_RHS);

         --  Generate:
         --    T : LHS_Typ := LHS;

         Insert_Before_And_Analyze (N,
           Make_Object_Declaration (Loc,
             Defining_Identifier => Ent,
             Object_Definition   => New_Occurrence_Of (LHS_Typ, Loc),
             Expression          => New_Copy_Tree (LHS)));

         --  Generate:
         --    LHS := ... T ...;

         Rewrite (N,
           Make_Assignment_Statement (Loc,
             Name       => Relocate_Node (LHS),
             Expression => New_RHS));

      --  Otherwise wrap the whole assignment statement in a procedure with an
      --  IN OUT parameter. The original assignment then becomes a call to the
      --  procedure with the left-hand side as an actual.

      else
         Ent := Make_Temporary (Loc, 'T');
         Replace_Target_Name (New_RHS);

         --  Generate:
         --    procedure P (T : in out LHS_Typ) is
         --    begin
         --       T := ... T ...;
         --    end P;

         Proc_Id := Make_Temporary (Loc, 'P');

         Insert_Before_And_Analyze (N,
           Make_Subprogram_Body (Loc,
             Specification              =>
               Make_Procedure_Specification (Loc,
                 Defining_Unit_Name       => Proc_Id,
                 Parameter_Specifications => New_List (
                   Make_Parameter_Specification (Loc,
                     Defining_Identifier => Ent,
                     In_Present          => True,
                     Out_Present         => True,
                     Parameter_Type      =>
                       New_Occurrence_Of (LHS_Typ, Loc)))),

             Declarations               => Empty_List,

             Handled_Statement_Sequence =>
               Make_Handled_Sequence_Of_Statements (Loc,
                 Statements => New_List (
                   Make_Assignment_Statement (Loc,
                     Name       => New_Occurrence_Of (Ent, Loc),
                     Expression => New_RHS)))));

         --  Generate:
         --    P (LHS);

         Rewrite (N,
           Make_Procedure_Call_Statement (Loc,
             Name                   => New_Occurrence_Of (Proc_Id, Loc),
             Parameter_Associations => New_List (Relocate_Node (LHS))));
      end if;

      --  Analyze rewritten node, either as assignment or procedure call

      Analyze (N);
   end Expand_Assign_With_Target_Names;

   -----------------------------------
   -- Expand_N_Assignment_Statement --
   -----------------------------------

   --  This procedure implements various cases where an assignment statement
   --  cannot just be passed on to the back end in untransformed state.

   procedure Expand_N_Assignment_Statement (N : Node_Id) is
      Crep : constant Boolean    := Change_Of_Representation (N);
      Lhs  : constant Node_Id    := Name (N);
      Loc  : constant Source_Ptr := Sloc (N);
      Rhs  : constant Node_Id    := Expression (N);
      Typ  : constant Entity_Id  := Underlying_Type (Etype (Lhs));
      Exp  : Node_Id;

   begin
      --  Special case to check right away, if the Componentwise_Assignment
      --  flag is set, this is a reanalysis from the expansion of the primitive
      --  assignment procedure for a tagged type, and all we need to do is to
      --  expand to assignment of components, because otherwise, we would get
      --  infinite recursion (since this looks like a tagged assignment which
      --  would normally try to *call* the primitive assignment procedure).

      if Componentwise_Assignment (N) then
         Expand_Assign_Record (N);
         return;
      end if;

      --  Defend against invalid subscripts on left side if we are in standard
      --  validity checking mode. No need to do this if we are checking all
      --  subscripts.

      --  Note that we do this right away, because there are some early return
      --  paths in this procedure, and this is required on all paths.

      if Validity_Checks_On
        and then Validity_Check_Default
        and then not Validity_Check_Subscripts
      then
         Check_Valid_Lvalue_Subscripts (Lhs);
      end if;

      --  Separate expansion if RHS contain target names. Note that assignment
      --  may already have been expanded if RHS is aggregate.

      if Nkind (N) = N_Assignment_Statement and then Has_Target_Names (N) then
         Expand_Assign_With_Target_Names (N);
         return;
      end if;

      --  Ada 2005 (AI-327): Handle assignment to priority of protected object

      --  Rewrite an assignment to X'Priority into a run-time call

      --   For example:         X'Priority := New_Prio_Expr;
      --   ...is expanded into  Set_Ceiling (X._Object, New_Prio_Expr);

      --  Note that although X'Priority is notionally an object, it is quite
      --  deliberately not defined as an aliased object in the RM. This means
      --  that it works fine to rewrite it as a call, without having to worry
      --  about complications that would other arise from X'Priority'Access,
      --  which is illegal, because of the lack of aliasing.

      if Ada_Version >= Ada_2005 then
         declare
            Call           : Node_Id;
            Conctyp        : Entity_Id;
            Ent            : Entity_Id;
            Subprg         : Entity_Id;
            RT_Subprg_Name : Node_Id;

         begin
            --  Handle chains of renamings

            Ent := Name (N);
            while Nkind (Ent) in N_Has_Entity
              and then Present (Entity (Ent))
              and then Present (Renamed_Object (Entity (Ent)))
            loop
               Ent := Renamed_Object (Entity (Ent));
            end loop;

            --  The attribute Priority applied to protected objects has been
            --  previously expanded into a call to the Get_Ceiling run-time
            --  subprogram. In restricted profiles this is not available.

            if Is_Expanded_Priority_Attribute (Ent) then

               --  Look for the enclosing concurrent type

               Conctyp := Current_Scope;
               while not Is_Concurrent_Type (Conctyp) loop
                  Conctyp := Scope (Conctyp);
               end loop;

               pragma Assert (Is_Protected_Type (Conctyp));

               --  Generate the first actual of the call

               Subprg := Current_Scope;
               while not Present (Protected_Body_Subprogram (Subprg)) loop
                  Subprg := Scope (Subprg);
               end loop;

               --  Select the appropriate run-time call

               if Number_Entries (Conctyp) = 0 then
                  RT_Subprg_Name :=
                    New_Occurrence_Of (RTE (RE_Set_Ceiling), Loc);
               else
                  RT_Subprg_Name :=
                    New_Occurrence_Of (RTE (RO_PE_Set_Ceiling), Loc);
               end if;

               Call :=
                 Make_Procedure_Call_Statement (Loc,
                   Name => RT_Subprg_Name,
                   Parameter_Associations => New_List (
                     New_Copy_Tree (First (Parameter_Associations (Ent))),
                     Relocate_Node (Expression (N))));

               Rewrite (N, Call);
               Analyze (N);

               return;
            end if;
         end;
      end if;

      --  Deal with assignment checks unless suppressed

      if not Suppress_Assignment_Checks (N) then

         --  First deal with generation of range check if required,
         --  and then predicate checks if the type carries a predicate.
         --  If the Rhs is an expression these tests may have been applied
         --  already. This is the case if the RHS is a type conversion.
         --  Other such redundant checks could be removed ???

         if Nkind (Rhs) /= N_Type_Conversion
           or else Entity (Subtype_Mark (Rhs)) /= Typ
         then
            if Do_Range_Check (Rhs) then
               Generate_Range_Check (Rhs, Typ, CE_Range_Check_Failed);
            end if;

            Apply_Predicate_Check (Rhs, Typ);
         end if;
      end if;

      --  Check for a special case where a high level transformation is
      --  required. If we have either of:

      --    P.field := rhs;
      --    P (sub) := rhs;

      --  where P is a reference to a bit packed array, then we have to unwind
      --  the assignment. The exact meaning of being a reference to a bit
      --  packed array is as follows:

      --    An indexed component whose prefix is a bit packed array is a
      --    reference to a bit packed array.

      --    An indexed component or selected component whose prefix is a
      --    reference to a bit packed array is itself a reference ot a
      --    bit packed array.

      --  The required transformation is

      --     Tnn : prefix_type := P;
      --     Tnn.field := rhs;
      --     P := Tnn;

      --  or

      --     Tnn : prefix_type := P;
      --     Tnn (subscr) := rhs;
      --     P := Tnn;

      --  Since P is going to be evaluated more than once, any subscripts
      --  in P must have their evaluation forced.

      if Nkind (Lhs) in N_Indexed_Component | N_Selected_Component
        and then Is_Ref_To_Bit_Packed_Array (Prefix (Lhs))
      then
         declare
            BPAR_Expr : constant Node_Id   := Relocate_Node (Prefix (Lhs));
            BPAR_Typ  : constant Entity_Id := Etype (BPAR_Expr);
            Tnn       : constant Entity_Id :=
                          Make_Temporary (Loc, 'T', BPAR_Expr);

         begin
            --  Insert the post assignment first, because we want to copy the
            --  BPAR_Expr tree before it gets analyzed in the context of the
            --  pre assignment. Note that we do not analyze the post assignment
            --  yet (we cannot till we have completed the analysis of the pre
            --  assignment). As usual, the analysis of this post assignment
            --  will happen on its own when we "run into" it after finishing
            --  the current assignment.

            Insert_After (N,
              Make_Assignment_Statement (Loc,
                Name       => New_Copy_Tree (BPAR_Expr),
                Expression => New_Occurrence_Of (Tnn, Loc)));

            --  At this stage BPAR_Expr is a reference to a bit packed array
            --  where the reference was not expanded in the original tree,
            --  since it was on the left side of an assignment. But in the
            --  pre-assignment statement (the object definition), BPAR_Expr
            --  will end up on the right-hand side, and must be reexpanded. To
            --  achieve this, we reset the analyzed flag of all selected and
            --  indexed components down to the actual indexed component for
            --  the packed array.

            Exp := BPAR_Expr;
            loop
               Set_Analyzed (Exp, False);

               if Nkind (Exp) in N_Indexed_Component | N_Selected_Component
               then
                  Exp := Prefix (Exp);
               else
                  exit;
               end if;
            end loop;

            --  Now we can insert and analyze the pre-assignment

            --  If the right-hand side requires a transient scope, it has
            --  already been placed on the stack. However, the declaration is
            --  inserted in the tree outside of this scope, and must reflect
            --  the proper scope for its variable. This awkward bit is forced
            --  by the stricter scope discipline imposed by GCC 2.97.

            declare
               Uses_Transient_Scope : constant Boolean :=
                                        Scope_Is_Transient
                                          and then N = Node_To_Be_Wrapped;

            begin
               if Uses_Transient_Scope then
                  Push_Scope (Scope (Current_Scope));
               end if;

               Insert_Before_And_Analyze (N,
                 Make_Object_Declaration (Loc,
                   Defining_Identifier => Tnn,
                   Object_Definition   => New_Occurrence_Of (BPAR_Typ, Loc),
                   Expression          => BPAR_Expr));

               if Uses_Transient_Scope then
                  Pop_Scope;
               end if;
            end;

            --  Now fix up the original assignment and continue processing

            Rewrite (Prefix (Lhs),
              New_Occurrence_Of (Tnn, Loc));

            --  We do not need to reanalyze that assignment, and we do not need
            --  to worry about references to the temporary, but we do need to
            --  make sure that the temporary is not marked as a true constant
            --  since we now have a generated assignment to it.

            Set_Is_True_Constant (Tnn, False);
         end;
      end if;

      --  When we have the appropriate type of aggregate in the expression (it
      --  has been determined during analysis of the aggregate by setting the
      --  delay flag), let's perform in place assignment and thus avoid
      --  creating a temporary.

      if Is_Delayed_Aggregate (Rhs) then
         Convert_Aggr_In_Assignment (N);
         Rewrite (N, Make_Null_Statement (Loc));
         Analyze (N);

         return;
      end if;

      --  Apply discriminant check if required. If Lhs is an access type to a
      --  designated type with discriminants, we must always check. If the
      --  type has unknown discriminants, more elaborate processing below.

      if Has_Discriminants (Etype (Lhs))
        and then not Has_Unknown_Discriminants (Etype (Lhs))
      then
         --  Skip discriminant check if change of representation. Will be
         --  done when the change of representation is expanded out.

         if not Crep then
            Apply_Discriminant_Check (Rhs, Etype (Lhs), Lhs);
         end if;

      --  If the type is private without discriminants, and the full type
      --  has discriminants (necessarily with defaults) a check may still be
      --  necessary if the Lhs is aliased. The private discriminants must be
      --  visible to build the discriminant constraints.

      --  Only an explicit dereference that comes from source indicates
      --  aliasing. Access to formals of protected operations and entries
      --  create dereferences but are not semantic aliasings.

      elsif Is_Private_Type (Etype (Lhs))
        and then Has_Discriminants (Typ)
        and then Nkind (Lhs) = N_Explicit_Dereference
        and then Comes_From_Source (Lhs)
      then
         declare
            Lt  : constant Entity_Id := Etype (Lhs);
            Ubt : Entity_Id          := Base_Type (Typ);

         begin
            --  In the case of an expander-generated record subtype whose base
            --  type still appears private, Typ will have been set to that
            --  private type rather than the underlying record type (because
            --  Underlying type will have returned the record subtype), so it's
            --  necessary to apply Underlying_Type again to the base type to
            --  get the record type we need for the discriminant check. Such
            --  subtypes can be created for assignments in certain cases, such
            --  as within an instantiation passed this kind of private type.
            --  It would be good to avoid this special test, but making changes
            --  to prevent this odd form of record subtype seems difficult. ???

            if Is_Private_Type (Ubt) then
               Ubt := Underlying_Type (Ubt);
            end if;

            Set_Etype (Lhs, Ubt);
            Rewrite (Rhs, OK_Convert_To (Base_Type (Ubt), Rhs));
            Apply_Discriminant_Check (Rhs, Ubt, Lhs);
            Set_Etype (Lhs, Lt);
         end;

      --  If the Lhs has a private type with unknown discriminants, it may
      --  have a full view with discriminants, but those are nameable only
      --  in the underlying type, so convert the Rhs to it before potential
      --  checking. Convert Lhs as well, otherwise the actual subtype might
      --  not be constructible. If the discriminants have defaults the type
      --  is unconstrained and there is nothing to check.
      --  Ditto if a private type with unknown discriminants has a full view
      --  that is an unconstrained array, in which case a length check is
      --  needed.

      elsif Has_Unknown_Discriminants (Base_Type (Etype (Lhs))) then
         if Has_Discriminants (Typ)
           and then not Has_Defaulted_Discriminants (Typ)
         then
            Rewrite (Rhs, OK_Convert_To (Base_Type (Typ), Rhs));
            Rewrite (Lhs, OK_Convert_To (Base_Type (Typ), Lhs));
            Apply_Discriminant_Check (Rhs, Typ, Lhs);

         elsif Is_Array_Type (Typ) and then Is_Constrained (Typ)  then
            Rewrite (Rhs, OK_Convert_To (Base_Type (Typ), Rhs));
            Rewrite (Lhs, OK_Convert_To (Base_Type (Typ), Lhs));
            Apply_Length_Check (Rhs, Typ);
         end if;

      --  In the access type case, we need the same discriminant check, and
      --  also range checks if we have an access to constrained array.

      elsif Is_Access_Type (Etype (Lhs))
        and then Is_Constrained (Designated_Type (Etype (Lhs)))
      then
         if Has_Discriminants (Designated_Type (Etype (Lhs))) then

            --  Skip discriminant check if change of representation. Will be
            --  done when the change of representation is expanded out.

            if not Crep then
               Apply_Discriminant_Check (Rhs, Etype (Lhs));
            end if;

         elsif Is_Array_Type (Designated_Type (Etype (Lhs))) then
            Apply_Range_Check (Rhs, Etype (Lhs));

            if Is_Constrained (Etype (Lhs)) then
               Apply_Length_Check (Rhs, Etype (Lhs));
            end if;
         end if;
      end if;

      --  Ada 2005 (AI-231): Generate the run-time check

      if Is_Access_Type (Typ)
        and then Can_Never_Be_Null (Etype (Lhs))
        and then not Can_Never_Be_Null (Etype (Rhs))

        --  If an actual is an out parameter of a null-excluding access
        --  type, there is access check on entry, so we set the flag
        --  Suppress_Assignment_Checks on the generated statement to
        --  assign the actual to the parameter block, and we do not want
        --  to generate an additional check at this point.

        and then not Suppress_Assignment_Checks (N)
      then
         Apply_Constraint_Check (Rhs, Etype (Lhs));
      end if;

      --  Ada 2012 (AI05-148): Update current accessibility level if Rhs is a
      --  stand-alone obj of an anonymous access type. Do not install the check
      --  when the Lhs denotes a container cursor and the Next function employs
      --  an access type, because this can never result in a dangling pointer.

      if Is_Access_Type (Typ)
        and then Is_Entity_Name (Lhs)
        and then Ekind (Entity (Lhs)) /= E_Loop_Parameter
        and then Present (Effective_Extra_Accessibility (Entity (Lhs)))
      then
         declare
            function Lhs_Entity return Entity_Id;
            --  Look through renames to find the underlying entity.
            --  For assignment to a rename, we don't care about the
            --  Enclosing_Dynamic_Scope of the rename declaration.

            ----------------
            -- Lhs_Entity --
            ----------------

            function Lhs_Entity return Entity_Id is
               Result : Entity_Id := Entity (Lhs);

            begin
               while Present (Renamed_Object (Result)) loop

                  --  Renamed_Object must return an Entity_Name here
                  --  because of preceding "Present (E_E_A (...))" test.

                  Result := Entity (Renamed_Object (Result));
               end loop;

               return Result;
            end Lhs_Entity;

            --  Local Declarations

            Access_Check : constant Node_Id :=
                             Make_Raise_Program_Error (Loc,
                               Condition =>
                                 Make_Op_Gt (Loc,
                                   Left_Opnd  =>
                                     Accessibility_Level (Rhs, Dynamic_Level),
                                   Right_Opnd =>
                                     Make_Integer_Literal (Loc,
                                       Intval =>
                                         Scope_Depth
                                           (Enclosing_Dynamic_Scope
                                             (Lhs_Entity)))),
                               Reason => PE_Accessibility_Check_Failed);

            Access_Level_Update : constant Node_Id :=
                                    Make_Assignment_Statement (Loc,
                                     Name       =>
                                       New_Occurrence_Of
                                         (Effective_Extra_Accessibility
                                            (Entity (Lhs)), Loc),
                                     Expression =>
                                       Accessibility_Level
                                         (Expr            => Rhs,
                                          Level           => Dynamic_Level,
                                          Allow_Alt_Model => False));

         begin
            if not Accessibility_Checks_Suppressed (Entity (Lhs)) then
               Insert_Action (N, Access_Check);
            end if;

            Insert_Action (N, Access_Level_Update);
         end;
      end if;

      --  Case of assignment to a bit packed array element. If there is a
      --  change of representation this must be expanded into components,
      --  otherwise this is a bit-field assignment.

      if Nkind (Lhs) = N_Indexed_Component
        and then Is_Bit_Packed_Array (Etype (Prefix (Lhs)))
      then
         --  Normal case, no change of representation

         if not Crep then
            Expand_Bit_Packed_Element_Set (N);
            return;

         --  Change of representation case

         else
            --  Generate the following, to force component-by-component
            --  assignments in an efficient way. Otherwise each component
            --  will require a temporary and two bit-field manipulations.

            --  T1 : Elmt_Type;
            --  T1 := RhS;
            --  Lhs := T1;

            declare
               Tnn : constant Entity_Id := Make_Temporary (Loc, 'T');
               Stats : List_Id;

            begin
               Stats :=
                 New_List (
                   Make_Object_Declaration (Loc,
                     Defining_Identifier => Tnn,
                     Object_Definition   =>
                       New_Occurrence_Of (Etype (Lhs), Loc)),
                   Make_Assignment_Statement (Loc,
                     Name       => New_Occurrence_Of (Tnn, Loc),
                     Expression => Relocate_Node (Rhs)),
                   Make_Assignment_Statement (Loc,
                     Name       => Relocate_Node (Lhs),
                     Expression => New_Occurrence_Of (Tnn, Loc)));

               Insert_Actions (N, Stats);
               Rewrite (N, Make_Null_Statement (Loc));
               Analyze (N);
            end;
         end if;

      --  Build-in-place function call case. This is for assignment statements
      --  that come from aggregate component associations or from init procs.
      --  User-written assignment statements with b-i-p calls are handled
      --  elsewhere.

      elsif Is_Build_In_Place_Function_Call (Rhs) then
         pragma Assert (not Comes_From_Source (N));
         Make_Build_In_Place_Call_In_Assignment (N, Rhs);

      elsif Is_Tagged_Type (Typ)
        or else (Needs_Finalization (Typ) and then not Is_Array_Type (Typ))
      then
         Tagged_Case : declare
            L                   : List_Id := No_List;
            Expand_Ctrl_Actions : constant Boolean := not No_Ctrl_Actions (N);

         begin
            --  In the controlled case, we ensure that function calls are
            --  evaluated before finalizing the target. In all cases, it makes
            --  the expansion easier if the side effects are removed first.

            Remove_Side_Effects (Lhs);
            Remove_Side_Effects (Rhs);

            --  Avoid recursion in the mechanism

            Set_Analyzed (N);

            --  If dispatching assignment, we need to dispatch to _assign

            if Is_Class_Wide_Type (Typ)

               --  If the type is tagged, we may as well use the predefined
               --  primitive assignment. This avoids inlining a lot of code
               --  and in the class-wide case, the assignment is replaced
               --  by a dispatching call to _assign. It is suppressed in the
               --  case of assignments created by the expander that correspond
               --  to initializations, where we do want to copy the tag
               --  (Expand_Ctrl_Actions flag is set False in this case). It is
               --  also suppressed if restriction No_Dispatching_Calls is in
               --  force because in that case predefined primitives are not
               --  generated.

               or else (Is_Tagged_Type (Typ)
                         and then Chars (Current_Scope) /= Name_uAssign
                         and then Expand_Ctrl_Actions
                         and then
                           not Restriction_Active (No_Dispatching_Calls))
            then
               --  We should normally not encounter any limited type here,
               --  except in the corner case where an assignment was not
               --  intended like the pathological case of a raise expression
               --  within a return statement.

               if Is_Limited_Type (Typ) then
                  pragma Assert (not Comes_From_Source (N));
                  return;
               end if;

               --  Fetch the primitive op _assign and proper type to call it.
               --  Because of possible conflicts between private and full view,
               --  fetch the proper type directly from the operation profile.

               declare
                  Op    : constant Entity_Id :=
                            Find_Prim_Op (Typ, Name_uAssign);
                  F_Typ : Entity_Id := Etype (First_Formal (Op));

               begin
                  --  If the assignment is dispatching, make sure to use the
                  --  proper type.

                  if Is_Class_Wide_Type (Typ) then
                     F_Typ := Class_Wide_Type (F_Typ);
                  end if;

                  L := New_List;

                  --  In case of assignment to a class-wide tagged type, before
                  --  the assignment we generate run-time check to ensure that
                  --  the tags of source and target match.

                  if not Tag_Checks_Suppressed (Typ)
                    and then Is_Class_Wide_Type (Typ)
                    and then Is_Tagged_Type (Typ)
                    and then Is_Tagged_Type (Underlying_Type (Etype (Rhs)))
                  then
                     declare
                        Lhs_Tag : Node_Id;
                        Rhs_Tag : Node_Id;

                     begin
                        if not Is_Interface (Typ) then
                           Lhs_Tag :=
                             Make_Selected_Component (Loc,
                               Prefix        => Duplicate_Subexpr (Lhs),
                               Selector_Name =>
                                 Make_Identifier (Loc, Name_uTag));
                           Rhs_Tag :=
                             Make_Selected_Component (Loc,
                               Prefix        => Duplicate_Subexpr (Rhs),
                               Selector_Name =>
                                 Make_Identifier (Loc, Name_uTag));
                        else
                           --  Displace the pointer to the base of the objects
                           --  applying 'Address, which is later expanded into
                           --  a call to RE_Base_Address.

                           Lhs_Tag :=
                             Make_Explicit_Dereference (Loc,
                               Prefix =>
                                 Unchecked_Convert_To (RTE (RE_Tag_Ptr),
                                   Make_Attribute_Reference (Loc,
                                     Prefix         => Duplicate_Subexpr (Lhs),
                                     Attribute_Name => Name_Address)));
                           Rhs_Tag :=
                             Make_Explicit_Dereference (Loc,
                               Prefix =>
                                 Unchecked_Convert_To (RTE (RE_Tag_Ptr),
                                   Make_Attribute_Reference (Loc,
                                     Prefix         => Duplicate_Subexpr (Rhs),
                                     Attribute_Name => Name_Address)));
                        end if;

                        Append_To (L,
                          Make_Raise_Constraint_Error (Loc,
                            Condition =>
                              Make_Op_Ne (Loc,
                                Left_Opnd  => Lhs_Tag,
                                Right_Opnd => Rhs_Tag),
                            Reason    => CE_Tag_Check_Failed));
                     end;
                  end if;

                  declare
                     Left_N  : Node_Id := Duplicate_Subexpr (Lhs);
                     Right_N : Node_Id := Duplicate_Subexpr (Rhs);

                  begin
                     --  In order to dispatch the call to _assign the type of
                     --  the actuals must match. Add conversion (if required).

                     if Etype (Lhs) /= F_Typ then
                        Left_N := Unchecked_Convert_To (F_Typ, Left_N);
                     end if;

                     if Etype (Rhs) /= F_Typ then
                        Right_N := Unchecked_Convert_To (F_Typ, Right_N);
                     end if;

                     Append_To (L,
                       Make_Procedure_Call_Statement (Loc,
                         Name => New_Occurrence_Of (Op, Loc),
                         Parameter_Associations => New_List (
                           Node1 => Left_N,
                           Node2 => Right_N)));
                  end;
               end;

            else
               L := Make_Tag_Ctrl_Assignment (N);

               --  We can't afford to have destructive Finalization Actions in
               --  the Self assignment case, so if the target and the source
               --  are not obviously different, code is generated to avoid the
               --  self assignment case:

               --    if lhs'address /= rhs'address then
               --       <code for controlled and/or tagged assignment>
               --    end if;

               --  Skip this if Restriction (No_Finalization) is active

               if not Statically_Different (Lhs, Rhs)
                 and then Expand_Ctrl_Actions
                 and then not Restriction_Active (No_Finalization)
               then
                  L := New_List (
                    Make_Implicit_If_Statement (N,
                      Condition =>
                        Make_Op_Ne (Loc,
                          Left_Opnd =>
                            Make_Attribute_Reference (Loc,
                              Prefix         => Duplicate_Subexpr (Lhs),
                              Attribute_Name => Name_Address),

                           Right_Opnd =>
                            Make_Attribute_Reference (Loc,
                              Prefix         => Duplicate_Subexpr (Rhs),
                              Attribute_Name => Name_Address)),

                      Then_Statements => L));
               end if;

               --  We need to set up an exception handler for implementing
               --  7.6.1(18). The remaining adjustments are tackled by the
               --  implementation of adjust for record_controllers (see
               --  s-finimp.adb).

               --  This is skipped if we have no finalization

               if Expand_Ctrl_Actions
                 and then not Restriction_Active (No_Finalization)
               then
                  L := New_List (
                    Make_Block_Statement (Loc,
                      Handled_Statement_Sequence =>
                        Make_Handled_Sequence_Of_Statements (Loc,
                          Statements => L,
                          Exception_Handlers => New_List (
                            Make_Handler_For_Ctrl_Operation (Loc)))));
               end if;
            end if;

            Rewrite (N,
              Make_Block_Statement (Loc,
                Handled_Statement_Sequence =>
                  Make_Handled_Sequence_Of_Statements (Loc, Statements => L)));

            --  If no restrictions on aborts, protect the whole assignment
            --  for controlled objects as per 9.8(11).

            if Needs_Finalization (Typ)
              and then Expand_Ctrl_Actions
              and then Abort_Allowed
            then
               declare
                  Blk : constant Entity_Id :=
                          New_Internal_Entity
                            (E_Block, Current_Scope, Sloc (N), 'B');
                  AUD : constant Entity_Id := RTE (RE_Abort_Undefer_Direct);

               begin
                  Set_Is_Abort_Block (N);

                  Set_Scope (Blk, Current_Scope);
                  Set_Etype (Blk, Standard_Void_Type);
                  Set_Identifier (N, New_Occurrence_Of (Blk, Sloc (N)));

                  Prepend_To (L, Build_Runtime_Call (Loc, RE_Abort_Defer));
                  Set_At_End_Proc (Handled_Statement_Sequence (N),
                    New_Occurrence_Of (AUD, Loc));

                  --  Present the Abort_Undefer_Direct function to the backend
                  --  so that it can inline the call to the function.

                  Add_Inlined_Body (AUD, N);

                  Expand_At_End_Handler
                    (Handled_Statement_Sequence (N), Blk);
               end;
            end if;

            --  N has been rewritten to a block statement for which it is
            --  known by construction that no checks are necessary: analyze
            --  it with all checks suppressed.

            Analyze (N, Suppress => All_Checks);
            return;
         end Tagged_Case;

      --  Array types

      elsif Is_Array_Type (Typ) then
         declare
            Actual_Rhs : Node_Id := Rhs;

         begin
            while Nkind (Actual_Rhs) in
                    N_Type_Conversion | N_Qualified_Expression
            loop
               Actual_Rhs := Expression (Actual_Rhs);
            end loop;

            Expand_Assign_Array (N, Actual_Rhs);
            return;
         end;

      --  Record types

      elsif Is_Record_Type (Typ) then
         Expand_Assign_Record (N);
         return;

      --  Scalar types. This is where we perform the processing related to the
      --  requirements of (RM 13.9.1(9-11)) concerning the handling of invalid
      --  scalar values.

      elsif Is_Scalar_Type (Typ) then

         --  Case where right side is known valid

         if Expr_Known_Valid (Rhs) then

            --  Here the right side is valid, so it is fine. The case to deal
            --  with is when the left side is a local variable reference whose
            --  value is not currently known to be valid. If this is the case,
            --  and the assignment appears in an unconditional context, then
            --  we can mark the left side as now being valid if one of these
            --  conditions holds:

            --    The expression of the right side has Do_Range_Check set so
            --    that we know a range check will be performed. Note that it
            --    can be the case that a range check is omitted because we
            --    make the assumption that we can assume validity for operands
            --    appearing in the right side in determining whether a range
            --    check is required

            --    The subtype of the right side matches the subtype of the
            --    left side. In this case, even though we have not checked
            --    the range of the right side, we know it is in range of its
            --    subtype if the expression is valid.

            if Is_Local_Variable_Reference (Lhs)
              and then not Is_Known_Valid (Entity (Lhs))
              and then In_Unconditional_Context (N)
            then
               if Do_Range_Check (Rhs)
                 or else Etype (Lhs) = Etype (Rhs)
               then
                  Set_Is_Known_Valid (Entity (Lhs), True);
               end if;
            end if;

         --  Case where right side may be invalid in the sense of the RM
         --  reference above. The RM does not require that we check for the
         --  validity on an assignment, but it does require that the assignment
         --  of an invalid value not cause erroneous behavior.

         --  The general approach in GNAT is to use the Is_Known_Valid flag
         --  to avoid the need for validity checking on assignments. However
         --  in some cases, we have to do validity checking in order to make
         --  sure that the setting of this flag is correct.

         else
            --  Validate right side if we are validating copies

            if Validity_Checks_On
              and then Validity_Check_Copies
            then
               --  Skip this if left-hand side is an array or record component
               --  and elementary component validity checks are suppressed.

               if Nkind (Lhs) in N_Selected_Component | N_Indexed_Component
                 and then not Validity_Check_Components
               then
                  null;
               else
                  Ensure_Valid (Rhs);
               end if;

               --  We can propagate this to the left side where appropriate

               if Is_Local_Variable_Reference (Lhs)
                 and then not Is_Known_Valid (Entity (Lhs))
                 and then In_Unconditional_Context (N)
               then
                  Set_Is_Known_Valid (Entity (Lhs), True);
               end if;

            --  Otherwise check to see what should be done

            --  If left side is a local variable, then we just set its flag to
            --  indicate that its value may no longer be valid, since we are
            --  copying a potentially invalid value.

            elsif Is_Local_Variable_Reference (Lhs) then
               Set_Is_Known_Valid (Entity (Lhs), False);

            --  Check for case of a nonlocal variable on the left side which
            --  is currently known to be valid. In this case, we simply ensure
            --  that the right side is valid. We only play the game of copying
            --  validity status for local variables, since we are doing this
            --  statically, not by tracing the full flow graph.

            elsif Is_Entity_Name (Lhs)
              and then Is_Known_Valid (Entity (Lhs))
            then
               --  Note: If Validity_Checking mode is set to none, we ignore
               --  the Ensure_Valid call so don't worry about that case here.

               Ensure_Valid (Rhs);

            --  In all other cases, we can safely copy an invalid value without
            --  worrying about the status of the left side. Since it is not a
            --  variable reference it will not be considered
            --  as being known to be valid in any case.

            else
               null;
            end if;
         end if;
      end if;

   exception
      when RE_Not_Available =>
         return;
   end Expand_N_Assignment_Statement;

   ------------------------------
   -- Expand_N_Block_Statement --
   ------------------------------

   --  Encode entity names defined in block statement

   procedure Expand_N_Block_Statement (N : Node_Id) is
   begin
      Qualify_Entity_Names (N);
   end Expand_N_Block_Statement;

   -----------------------------
   -- Expand_N_Case_Statement --
   -----------------------------

   procedure Expand_N_Case_Statement (N : Node_Id) is
      Loc            : constant Source_Ptr := Sloc (N);
      Expr           : constant Node_Id    := Expression (N);
      From_Cond_Expr : constant Boolean    := From_Conditional_Expression (N);
      Alt            : Node_Id;
      Len            : Nat;
      Cond           : Node_Id;
      Choice         : Node_Id;
      Chlist         : List_Id;

      function Expand_General_Case_Statement return Node_Id;
      --  Expand a case statement whose selecting expression is not discrete

      -----------------------------------
      -- Expand_General_Case_Statement --
      -----------------------------------

      function Expand_General_Case_Statement return Node_Id is
         --  expand into a block statement

         Selector : constant Entity_Id :=
           Make_Temporary (Loc, 'J');

         function Selector_Subtype_Mark return Node_Id is
           (New_Occurrence_Of (Etype (Expr), Loc));

         Renamed_Name : constant Node_Id :=
           (if Is_Name_Reference (Expr)
              then Expr
              else Make_Qualified_Expression (Loc,
                     Subtype_Mark => Selector_Subtype_Mark,
                     Expression   => Expr));

         Selector_Decl : constant Node_Id :=
           Make_Object_Renaming_Declaration (Loc,
             Defining_Identifier => Selector,
             Subtype_Mark        => Selector_Subtype_Mark,
             Name                => Renamed_Name);

         First_Alt : constant Node_Id := First (Alternatives (N));

         function Choice_Index_Decl_If_Needed return Node_Id;
         --  If we are going to need a choice index object (that is, if
         --  Multidefined_Bindings is true for at least one of the case
         --  alternatives), then create and return that object's declaration.
         --  Otherwise, return Empty; no need for a decl in that case because
         --  it would never be referenced.

         ---------------------------------
         -- Choice_Index_Decl_If_Needed --
         ---------------------------------

         function Choice_Index_Decl_If_Needed return Node_Id is
            Alt : Node_Id := First_Alt;
         begin
            while Present (Alt) loop
               if Multidefined_Bindings (Alt) then
                  return Make_Object_Declaration
                    (Sloc => Loc,
                     Defining_Identifier =>
                       Make_Temporary (Loc, 'K'),
                     Object_Definition =>
                       New_Occurrence_Of (Standard_Positive, Loc));
               end if;

               Next (Alt);
            end loop;
            return Empty; -- decl not needed
         end Choice_Index_Decl_If_Needed;

         Choice_Index_Decl : constant Node_Id := Choice_Index_Decl_If_Needed;

         function Pattern_Match
           (Pattern      : Node_Id;
            Object       : Node_Id;
            Choice_Index : Natural;
            Alt          : Node_Id;
            Suppress_Choice_Index_Update : Boolean := False) return Node_Id;
         --  Returns a Boolean-valued expression indicating a pattern match
         --  for a given pattern and object. If Choice_Index is nonzero,
         --  then Choice_Index is assigned to Choice_Index_Decl (unless
         --  Suppress_Choice_Index_Update is specified, which should only
         --  be the case for a recursive call where the caller has already
         --  taken care of the update). Pattern occurs as a choice (or as a
         --  subexpression of a choice) of the case statement alternative Alt.

         function Top_Level_Pattern_Match_Condition
           (Alt : Node_Id) return Node_Id;
         --  Returns a Boolean-valued expression indicating a pattern match
         --  for the given alternative's list of choices.

         -------------------
         -- Pattern_Match --
         -------------------

         function Pattern_Match
           (Pattern      : Node_Id;
            Object       : Node_Id;
            Choice_Index : Natural;
            Alt          : Node_Id;
            Suppress_Choice_Index_Update : Boolean := False) return Node_Id
         is
            function Update_Choice_Index return Node_Id is (
              Make_Assignment_Statement (Loc,
                Name       =>
                  New_Occurrence_Of
                    (Defining_Identifier (Choice_Index_Decl), Loc),
                Expression => Make_Integer_Literal (Loc, Pos (Choice_Index))));

            function PM
              (Pattern      : Node_Id;
               Object       : Node_Id;
               Choice_Index : Natural := Pattern_Match.Choice_Index;
               Alt          : Node_Id := Pattern_Match.Alt;
               Suppress_Choice_Index_Update : Boolean :=
                 Pattern_Match.Suppress_Choice_Index_Update) return Node_Id
              renames Pattern_Match;
            --  convenient rename for recursive calls

            function Indexed_Element (Idx : Pos) return Node_Id;
            --  Returns the Nth (well, ok, the Idxth) element of Object

            ---------------------
            -- Indexed_Element --
            ---------------------

            function Indexed_Element (Idx : Pos) return Node_Id is
               Obj_Index : constant Node_Id :=
                 Make_Op_Add (Loc,
                   Left_Opnd =>
                     Make_Attribute_Reference (Loc,
                       Attribute_Name => Name_First,
                       Prefix => New_Copy_Tree (Object)),
                   Right_Opnd =>
                     Make_Integer_Literal (Loc, Idx - 1));
            begin
               return Make_Indexed_Component (Loc,
                        Prefix => New_Copy_Tree (Object),
                        Expressions => New_List (Obj_Index));
            end Indexed_Element;

         --  Start of processing for Pattern_Match

         begin
            if Choice_Index /= 0 and not Suppress_Choice_Index_Update then
               pragma Assert (Present (Choice_Index_Decl));

               --  Add Choice_Index update as a side effect of evaluating
               --  this condition and try again, this time suppressing
               --  Choice_Index update.

               return Make_Expression_With_Actions (Loc,
                        Actions => New_List (Update_Choice_Index),
                        Expression =>
                          PM (Pattern, Object,
                              Suppress_Choice_Index_Update => True));
            end if;

            if Nkind (Pattern) in N_Has_Etype
              and then Is_Discrete_Type (Etype (Pattern))
              and then Compile_Time_Known_Value (Pattern)
            then
               declare
                  Val : Node_Id;
               begin
                  if Is_Enumeration_Type (Etype (Pattern)) then
                     Val := Get_Enum_Lit_From_Pos
                              (Etype (Pattern), Expr_Value (Pattern), Loc);
                  else
                     Val := Make_Integer_Literal (Loc, Expr_Value (Pattern));
                  end if;
                  return Make_Op_Eq (Loc, Object, Val);
               end;
            end if;

            case Nkind (Pattern) is
               when N_Aggregate =>
                  declare
                     Result : Node_Id;
                  begin
                     if Is_Array_Type (Etype (Pattern)) then

                        --  Nonpositional aggregates currently unimplemented.
                        --  We flag that case during analysis, so an assertion
                        --  is ok here.
                        --
                        pragma Assert
                          (not Is_Non_Empty_List
                                 (Component_Associations (Pattern)));

                        declare
                           Agg_Length : constant Node_Id :=
                             Make_Integer_Literal (Loc,
                               List_Length (Expressions (Pattern)));

                           Obj_Length : constant Node_Id :=
                             Make_Attribute_Reference (Loc,
                               Attribute_Name => Name_Length,
                               Prefix => New_Copy_Tree (Object));
                        begin
                           Result := Make_Op_Eq (Loc,
                                       Left_Opnd  => Obj_Length,
                                       Right_Opnd => Agg_Length);
                        end;

                        declare
                           Expr : Node_Id := First (Expressions (Pattern));
                           Idx  : Pos := 1;
                        begin
                           while Present (Expr) loop
                              Result :=
                                Make_And_Then (Loc,
                                  Left_Opnd  => Result,
                                  Right_Opnd =>
                                    PM (Pattern => Expr,
                                        Object => Indexed_Element (Idx)));
                              Next (Expr);
                              Idx := Idx + 1;
                           end loop;
                        end;

                        return Result;
                     end if;

                     --  positional notation should have been normalized
                     pragma Assert (No (Expressions (Pattern)));

                     declare
                        Component_Assoc : Node_Id
                          := First (Component_Associations (Pattern));
                        Choice : Node_Id;

                        function Subobject return Node_Id is
                          (Make_Selected_Component (Loc,
                             Prefix => New_Copy_Tree (Object),
                             Selector_Name => New_Occurrence_Of
                                                (Entity (Choice), Loc)));
                     begin
                        Result := New_Occurrence_Of (Standard_True, Loc);

                        while Present (Component_Assoc) loop
                           Choice := First (Choices (Component_Assoc));
                           while Present (Choice) loop
                              pragma Assert
                                (Is_Entity_Name (Choice)
                                   and then Ekind (Entity (Choice))
                                              in E_Discriminant | E_Component);

                              if Box_Present (Component_Assoc) then
                                 --  Box matches anything

                                 pragma Assert
                                   (No (Expression (Component_Assoc)));
                              else
                                 Result := Make_And_Then (Loc,
                                             Left_Opnd  => Result,
                                             Right_Opnd =>
                                               PM (Pattern =>
                                                     Expression
                                                       (Component_Assoc),
                                                   Object => Subobject));
                              end if;

                              --  If this component association defines
                              --  (in the case where the pattern matches)
                              --  the value of a binding object, then
                              --  prepend to the statement list for this
                              --  alternative an assignment to the binding
                              --  object. This assignment will be conditional
                              --  if there is more than one choice.

                              if Binding_Chars (Component_Assoc) /= No_Name
                              then
                                 declare
                                    Decl_Chars : constant Name_Id :=
                                      Binding_Chars (Component_Assoc);

                                    Block_Stmt : constant Node_Id :=
                                      First (Statements (Alt));
                                    pragma Assert
                                      (Nkind (Block_Stmt) = N_Block_Statement);
                                    pragma Assert (No (Next (Block_Stmt)));
                                    Decl : Node_Id
                                      := First (Declarations (Block_Stmt));
                                    Def_Id : Node_Id := Empty;

                                    Assignment_Stmt : Node_Id;
                                    Condition       : Node_Id;
                                    Prepended_Stmt  : Node_Id;
                                 begin
                                    --  find the variable to be modified
                                    while No (Def_Id) or else
                                      Chars (Def_Id) /= Decl_Chars
                                    loop
                                       Def_Id := Defining_Identifier (Decl);
                                       Next (Decl);
                                    end loop;

                                    Assignment_Stmt :=
                                      Make_Assignment_Statement (Loc,
                                        Name       => New_Occurrence_Of
                                                        (Def_Id, Loc),
                                        Expression => Subobject);

                                    --  conditional if multiple choices

                                    if Present (Choice_Index_Decl) then
                                       Condition :=
                                         Make_Op_Eq (Loc,
                                           New_Occurrence_Of
                                             (Defining_Identifier
                                                (Choice_Index_Decl), Loc),
                                          Make_Integer_Literal
                                            (Loc, Int (Choice_Index)));

                                       Prepended_Stmt :=
                                         Make_If_Statement (Loc,
                                           Condition       => Condition,
                                           Then_Statements =>
                                             New_List (Assignment_Stmt));
                                    else
                                       --  assignment is unconditional
                                       Prepended_Stmt := Assignment_Stmt;
                                    end if;

                                    declare
                                       HSS : constant Node_Id :=
                                         Handled_Statement_Sequence
                                           (Block_Stmt);
                                    begin
                                       Prepend (Prepended_Stmt,
                                                Statements (HSS));

                                       Set_Analyzed (Block_Stmt, False);
                                       Set_Analyzed (HSS, False);
                                    end;
                                 end;
                              end if;

                              Next (Choice);
                           end loop;

                           Next (Component_Assoc);
                        end loop;
                     end;
                     return Result;
                  end;

               when N_String_Literal =>
                  return Result : Node_Id do
                     declare
                        Char_Type : constant Entity_Id :=
                          Root_Type (Component_Type (Etype (Pattern)));

                        --  If the component type is not a standard character
                        --  type then this string lit should have already been
                        --  transformed into an aggregate in
                        --  Resolve_String_Literal.
                        --
                        pragma Assert (Is_Standard_Character_Type (Char_Type));

                        Str    : constant String_Id  := Strval (Pattern);
                        Strlen : constant Nat        := String_Length (Str);

                        Lit_Length : constant Node_Id :=
                          Make_Integer_Literal (Loc, Strlen);

                        Obj_Length : constant Node_Id :=
                          Make_Attribute_Reference (Loc,
                            Attribute_Name => Name_Length,
                            Prefix => New_Copy_Tree (Object));
                     begin
                        Result := Make_Op_Eq (Loc,
                                    Left_Opnd  => Obj_Length,
                                    Right_Opnd => Lit_Length);

                        for Idx in 1 .. Strlen loop
                           declare
                              C           : constant Char_Code :=
                                Get_String_Char (Str, Idx);
                              Obj_Element : constant Node_Id :=
                                Indexed_Element (Idx);
                              Char_Lit    : Node_Id;
                           begin
                              Set_Character_Literal_Name (C);
                              Char_Lit :=
                                Make_Character_Literal (Loc,
                                  Chars              => Name_Find,
                                  Char_Literal_Value => UI_From_CC (C));

                              Result :=
                                Make_And_Then (Loc,
                                  Left_Opnd  => Result,
                                  Right_Opnd =>
                                    Make_Op_Eq (Loc,
                                      Left_Opnd  => Obj_Element,
                                      Right_Opnd => Char_Lit));
                           end;
                        end loop;
                     end;
                  end return;

               when N_Qualified_Expression =>
                  return Make_And_Then (Loc,
                    Left_Opnd  => Make_In (Loc,
                      Left_Opnd  => New_Copy_Tree (Object),
                      Right_Opnd => New_Copy_Tree (Subtype_Mark (Pattern))),
                    Right_Opnd =>
                      PM (Pattern => Expression (Pattern),
                          Object  => New_Copy_Tree (Object)));

               when N_Identifier | N_Expanded_Name =>
                  if Is_Type (Entity (Pattern)) then
                     return Make_In (Loc,
                       Left_Opnd  => New_Copy_Tree (Object),
                       Right_Opnd => New_Occurrence_Of
                                       (Entity (Pattern), Loc));
                  elsif Ekind (Entity (Pattern)) = E_Constant then
                     return PM (Pattern =>
                                  Expression (Parent (Entity (Pattern))),
                                Object => Object);
                  end if;

               when N_Others_Choice =>
                  return New_Occurrence_Of (Standard_True, Loc);

               when N_Type_Conversion =>
                  --  aggregate expansion sometimes introduces conversions
                  if not Comes_From_Source (Pattern)
                    and then Base_Type (Etype (Pattern))
                           = Base_Type (Etype (Expression (Pattern)))
                  then
                     return PM (Expression (Pattern), Object);
                  end if;

               when others =>
                  null;
            end case;

            --  Avoid cascading errors
            pragma Assert (Serious_Errors_Detected > 0);
            return New_Occurrence_Of (Standard_True, Loc);
         end Pattern_Match;

         ---------------------------------------
         -- Top_Level_Pattern_Match_Condition --
         ---------------------------------------

         function Top_Level_Pattern_Match_Condition
           (Alt : Node_Id) return Node_Id
         is
            Top_Level_Object : constant Node_Id :=
              New_Occurrence_Of (Selector, Loc);

            Choices : constant List_Id := Discrete_Choices (Alt);

            First_Choice : constant Node_Id := First (Choices);
            Subsequent : Node_Id := Next (First_Choice);

            Choice_Index : Natural := 0;
         begin
            if Multidefined_Bindings (Alt) then
               Choice_Index := 1;
            end if;

            return Result : Node_Id :=
              Pattern_Match (Pattern      => First_Choice,
                             Object       => Top_Level_Object,
                             Choice_Index => Choice_Index,
                             Alt          => Alt)
            do
               while Present (Subsequent) loop
                  if Choice_Index /= 0 then
                     Choice_Index := Choice_Index + 1;
                  end if;

                  Result := Make_Or_Else (Loc,
                    Left_Opnd  => Result,
                    Right_Opnd => Pattern_Match
                                    (Pattern      => Subsequent,
                                     Object       => Top_Level_Object,
                                     Choice_Index => Choice_Index,
                                     Alt          => Alt));
                  Subsequent := Next (Subsequent);
               end loop;
            end return;
         end Top_Level_Pattern_Match_Condition;

         function Elsif_Parts return List_Id;
         --  Process subsequent alternatives

         -----------------
         -- Elsif_Parts --
         -----------------

         function Elsif_Parts return List_Id is
            Alt : Node_Id := First_Alt;
            Result : constant List_Id := New_List;
         begin
            loop
               Alt := Next (Alt);
               exit when No (Alt);

               Append (Make_Elsif_Part (Loc,
                         Condition => Top_Level_Pattern_Match_Condition (Alt),
                         Then_Statements => Statements (Alt)),
                       Result);
            end loop;
            return Result;
         end Elsif_Parts;

         function Else_Statements return List_Id;
         --  Returns a "raise Constraint_Error" statement if
         --  exception propagate is permitted and No_List otherwise.

         ---------------------
         -- Else_Statements --
         ---------------------

         function Else_Statements return List_Id is
         begin
            if Restriction_Active (No_Exception_Propagation) then
               return No_List;
            else
               return New_List (Make_Raise_Constraint_Error (Loc,
                                  Reason => CE_Invalid_Data));
            end if;
         end Else_Statements;

         --  Local constants

         If_Stmt : constant Node_Id :=
           Make_If_Statement (Loc,
              Condition       => Top_Level_Pattern_Match_Condition (First_Alt),
              Then_Statements => Statements (First_Alt),
              Elsif_Parts     => Elsif_Parts,
              Else_Statements => Else_Statements);

         Declarations : constant List_Id := New_List (Selector_Decl);

      --  Start of processing for Expand_General_Case_Statment

      begin
         if Present (Choice_Index_Decl) then
            Append_To (Declarations, Choice_Index_Decl);
         end if;

         return Make_Block_Statement (Loc,
            Declarations => Declarations,
            Handled_Statement_Sequence =>
              Make_Handled_Sequence_Of_Statements (Loc,
                Statements => New_List (If_Stmt)));
      end Expand_General_Case_Statement;

   --  Start of processing for Expand_N_Case_Statement

   begin
      if Extensions_Allowed and then not Is_Discrete_Type (Etype (Expr)) then
         Rewrite (N, Expand_General_Case_Statement);
         Analyze (N);
         Expand (N);
         return;
      end if;

      --  Check for the situation where we know at compile time which branch
      --  will be taken.

      --  If the value is static but its subtype is predicated and the value
      --  does not obey the predicate, the value is marked non-static, and
      --  there can be no corresponding static alternative. In that case we
      --  replace the case statement with an exception, regardless of whether
      --  assertions are enabled or not, unless predicates are ignored.

      if Compile_Time_Known_Value (Expr)
        and then Has_Predicates (Etype (Expr))
        and then not Predicates_Ignored (Etype (Expr))
        and then not Is_OK_Static_Expression (Expr)
      then
         Rewrite (N,
           Make_Raise_Constraint_Error (Loc, Reason => CE_Invalid_Data));
         Analyze (N);
         return;

      elsif Compile_Time_Known_Value (Expr)
        and then (not Has_Predicates (Etype (Expr))
                   or else Is_Static_Expression (Expr))
      then
         Alt := Find_Static_Alternative (N);

         --  Do not consider controlled objects found in a case statement which
         --  actually models a case expression because their early finalization
         --  will affect the result of the expression.

         if not From_Conditional_Expression (N) then
            Process_Statements_For_Controlled_Objects (Alt);
         end if;

         --  Move statements from this alternative after the case statement.
         --  They are already analyzed, so will be skipped by the analyzer.

         Insert_List_After (N, Statements (Alt));

         --  That leaves the case statement as a shell. So now we can kill all
         --  other alternatives in the case statement.

         Kill_Dead_Code (Expression (N));

         declare
            Dead_Alt : Node_Id;

         begin
            --  Loop through case alternatives, skipping pragmas, and skipping
            --  the one alternative that we select (and therefore retain).

            Dead_Alt := First (Alternatives (N));
            while Present (Dead_Alt) loop
               if Dead_Alt /= Alt
                 and then Nkind (Dead_Alt) = N_Case_Statement_Alternative
               then
                  Kill_Dead_Code (Statements (Dead_Alt), Warn_On_Deleted_Code);
               end if;

               Next (Dead_Alt);
            end loop;
         end;

         Rewrite (N, Make_Null_Statement (Loc));
         return;
      end if;

      --  Here if the choice is not determined at compile time

      declare
         Last_Alt : constant Node_Id := Last (Alternatives (N));

         Others_Present : Boolean;
         Others_Node    : Node_Id;

         Then_Stms : List_Id;
         Else_Stms : List_Id;

      begin
         if Nkind (First (Discrete_Choices (Last_Alt))) = N_Others_Choice then
            Others_Present := True;
            Others_Node    := Last_Alt;
         else
            Others_Present := False;
         end if;

         --  First step is to worry about possible invalid argument. The RM
         --  requires (RM 5.4(13)) that if the result is invalid (e.g. it is
         --  outside the base range), then Constraint_Error must be raised.

         --  Case of validity check required (validity checks are on, the
         --  expression is not known to be valid, and the case statement
         --  comes from source -- no need to validity check internally
         --  generated case statements).

         if Validity_Check_Default
           and then not Predicates_Ignored (Etype (Expr))
         then
            --  Recognize the simple case where Expr is an object reference
            --  and the case statement is directly preceded by an
            --  "if Obj'Valid then": in this case, do not emit another validity
            --  check.

            declare
               Check_Validity : Boolean := True;
               Attr           : Node_Id;
            begin
               if Nkind (Expr) = N_Identifier
                 and then Nkind (Parent (N)) = N_If_Statement
                 and then Nkind (Original_Node (Condition (Parent (N))))
                           = N_Attribute_Reference
                 and then No (Prev (N))
               then
                  Attr := Original_Node (Condition (Parent (N)));

                  if Attribute_Name (Attr) = Name_Valid
                    and then Nkind (Prefix (Attr)) = N_Identifier
                    and then Entity (Prefix (Attr)) = Entity (Expr)
                  then
                     Check_Validity := False;
                  end if;
               end if;

               if Check_Validity then
                  Ensure_Valid (Expr);
               end if;
            end;
         end if;

         --  If there is only a single alternative, just replace it with the
         --  sequence of statements since obviously that is what is going to
         --  be executed in all cases.

         Len := List_Length (Alternatives (N));

         if Len = 1 then

            --  We still need to evaluate the expression if it has any side
            --  effects.

            Remove_Side_Effects (Expression (N));
            Alt := First (Alternatives (N));

            --  Do not consider controlled objects found in a case statement
            --  which actually models a case expression because their early
            --  finalization will affect the result of the expression.

            if not From_Conditional_Expression (N) then
               Process_Statements_For_Controlled_Objects (Alt);
            end if;

            Insert_List_After (N, Statements (Alt));

            --  That leaves the case statement as a shell. The alternative that
            --  will be executed is reset to a null list. So now we can kill
            --  the entire case statement.

            Kill_Dead_Code (Expression (N));
            Rewrite (N, Make_Null_Statement (Loc));
            return;

         --  An optimization. If there are only two alternatives, and only
         --  a single choice, then rewrite the whole case statement as an
         --  if statement, since this can result in subsequent optimizations.
         --  This helps not only with case statements in the source of a
         --  simple form, but also with generated code (discriminant check
         --  functions in particular).

         --  Note: it is OK to do this before expanding out choices for any
         --  static predicates, since the if statement processing will handle
         --  the static predicate case fine.

         elsif Len = 2 then
            Chlist := Discrete_Choices (First (Alternatives (N)));

            if List_Length (Chlist) = 1 then
               Choice := First (Chlist);

               Then_Stms := Statements (First (Alternatives (N)));
               Else_Stms := Statements (Last  (Alternatives (N)));

               --  For TRUE, generate "expression", not expression = true

               if Nkind (Choice) = N_Identifier
                 and then Entity (Choice) = Standard_True
               then
                  Cond := Expression (N);

               --  For FALSE, generate "expression" and switch then/else

               elsif Nkind (Choice) = N_Identifier
                 and then Entity (Choice) = Standard_False
               then
                  Cond := Expression (N);
                  Else_Stms := Statements (First (Alternatives (N)));
                  Then_Stms := Statements (Last  (Alternatives (N)));

               --  For a range, generate "expression in range"

               elsif Nkind (Choice) = N_Range
                 or else (Nkind (Choice) = N_Attribute_Reference
                           and then Attribute_Name (Choice) = Name_Range)
                 or else (Is_Entity_Name (Choice)
                           and then Is_Type (Entity (Choice)))
               then
                  Cond :=
                    Make_In (Loc,
                      Left_Opnd  => Expression (N),
                      Right_Opnd => Relocate_Node (Choice));

               --  A subtype indication is not a legal operator in a membership
               --  test, so retrieve its range.

               elsif Nkind (Choice) = N_Subtype_Indication then
                  Cond :=
                    Make_In (Loc,
                      Left_Opnd  => Expression (N),
                      Right_Opnd =>
                        Relocate_Node
                          (Range_Expression (Constraint (Choice))));

               --  For any other subexpression "expression = value"

               else
                  Cond :=
                    Make_Op_Eq (Loc,
                      Left_Opnd  => Expression (N),
                      Right_Opnd => Relocate_Node (Choice));
               end if;

               --  Now rewrite the case as an IF

               Rewrite (N,
                 Make_If_Statement (Loc,
                   Condition => Cond,
                   Then_Statements => Then_Stms,
                   Else_Statements => Else_Stms));

               --  The rewritten if statement needs to inherit whether the
               --  case statement was expanded from a conditional expression,
               --  for proper handling of nested controlled objects.

               Set_From_Conditional_Expression (N, From_Cond_Expr);

               Analyze (N);

               return;
            end if;
         end if;

         --  If the last alternative is not an Others choice, replace it with
         --  an N_Others_Choice. Note that we do not bother to call Analyze on
         --  the modified case statement, since it's only effect would be to
         --  compute the contents of the Others_Discrete_Choices which is not
         --  needed by the back end anyway.

         --  The reason for this is that the back end always needs some default
         --  for a switch, so if we have not supplied one in the processing
         --  above for validity checking, then we need to supply one here.

         if not Others_Present then
            Others_Node := Make_Others_Choice (Sloc (Last_Alt));

            --  If Predicates_Ignored is true the value does not satisfy the
            --  predicate, and there is no Others choice, Constraint_Error
            --  must be raised (4.5.7 (21/3)).

            if Predicates_Ignored (Etype (Expr)) then
               declare
                  Except  : constant Node_Id :=
                              Make_Raise_Constraint_Error (Loc,
                                Reason => CE_Invalid_Data);
                  New_Alt : constant Node_Id :=
                              Make_Case_Statement_Alternative (Loc,
                                Discrete_Choices => New_List (
                                  Make_Others_Choice (Loc)),
                                Statements       => New_List (Except));

               begin
                  Append (New_Alt, Alternatives (N));
                  Analyze_And_Resolve (Except);
               end;

            else
               Set_Others_Discrete_Choices
                 (Others_Node, Discrete_Choices (Last_Alt));
               Set_Discrete_Choices (Last_Alt, New_List (Others_Node));
            end if;

         end if;

         --  Deal with possible declarations of controlled objects, and also
         --  with rewriting choice sequences for static predicate references.

         Alt := First_Non_Pragma (Alternatives (N));
         while Present (Alt) loop

            --  Do not consider controlled objects found in a case statement
            --  which actually models a case expression because their early
            --  finalization will affect the result of the expression.

            if not From_Conditional_Expression (N) then
               Process_Statements_For_Controlled_Objects (Alt);
            end if;

            if Has_SP_Choice (Alt) then
               Expand_Static_Predicates_In_Choices (Alt);
            end if;

            Next_Non_Pragma (Alt);
         end loop;
      end;
   end Expand_N_Case_Statement;

   -----------------------------
   -- Expand_N_Exit_Statement --
   -----------------------------

   --  The only processing required is to deal with a possible C/Fortran
   --  boolean value used as the condition for the exit statement.

   procedure Expand_N_Exit_Statement (N : Node_Id) is
   begin
      Adjust_Condition (Condition (N));
   end Expand_N_Exit_Statement;

   ----------------------------------
   -- Expand_Formal_Container_Loop --
   ----------------------------------

   procedure Expand_Formal_Container_Loop (N : Node_Id) is
      Loc       : constant Source_Ptr := Sloc (N);
      Isc       : constant Node_Id    := Iteration_Scheme (N);
      I_Spec    : constant Node_Id    := Iterator_Specification (Isc);
      Cursor    : constant Entity_Id  := Defining_Identifier (I_Spec);
      Container : constant Node_Id    := Entity (Name (I_Spec));
      Stats     : constant List_Id    := Statements (N);

      Advance   : Node_Id;
      Init_Decl : Node_Id;
      Init_Name : Entity_Id;
      New_Loop  : Node_Id;

   begin
      --  The expansion of a formal container loop resembles the one for Ada
      --  containers. The only difference is that the primitives mention the
      --  domain of iteration explicitly, and function First applied to the
      --  container yields a cursor directly.

      --    Cursor : Cursor_type := First (Container);
      --    while Has_Element (Cursor, Container) loop
      --          <original loop statements>
      --       Cursor := Next (Container, Cursor);
      --    end loop;

      Build_Formal_Container_Iteration
        (N, Container, Cursor, Init_Decl, Advance, New_Loop);

      Append_To (Stats, Advance);

      --  Build a block to capture declaration of the cursor

      Rewrite (N,
        Make_Block_Statement (Loc,
          Declarations               => New_List (Init_Decl),
          Handled_Statement_Sequence =>
            Make_Handled_Sequence_Of_Statements (Loc,
              Statements => New_List (New_Loop))));

      --  The loop parameter is declared by an object declaration, but within
      --  the loop we must prevent user assignments to it, so we analyze the
      --  declaration and reset the entity kind, before analyzing the rest of
      --  the loop.

      Analyze (Init_Decl);
      Init_Name := Defining_Identifier (Init_Decl);
      Mutate_Ekind (Init_Name, E_Loop_Parameter);

      --  The cursor was marked as a loop parameter to prevent user assignments
      --  to it, however this renders the advancement step illegal as it is not
      --  possible to change the value of a constant. Flag the advancement step
      --  as a legal form of assignment to remedy this side effect.

      Set_Assignment_OK (Name (Advance));
      Analyze (N);

      --  Because we have to analyze the initial declaration of the loop
      --  parameter multiple times its scope is incorrectly set at this point
      --  to the one surrounding the block statement - so set the scope
      --  manually to be the actual block statement, and indicate that it is
      --  not visible after the block has been analyzed.

      Set_Scope (Init_Name, Entity (Identifier (N)));
      Set_Is_Immediately_Visible (Init_Name, False);
   end Expand_Formal_Container_Loop;

   ------------------------------------------
   -- Expand_Formal_Container_Element_Loop --
   ------------------------------------------

   procedure Expand_Formal_Container_Element_Loop (N : Node_Id) is
      Loc           : constant Source_Ptr := Sloc (N);
      Isc           : constant Node_Id    := Iteration_Scheme (N);
      I_Spec        : constant Node_Id    := Iterator_Specification (Isc);
      Element       : constant Entity_Id  := Defining_Identifier (I_Spec);
      Container     : constant Node_Id    := Entity (Name (I_Spec));
      Container_Typ : constant Entity_Id  := Base_Type (Etype (Container));
      Stats         : constant List_Id    := Statements (N);

      Cursor    : constant Entity_Id :=
                    Make_Defining_Identifier (Loc,
                      Chars => New_External_Name (Chars (Element), 'C'));
      Elmt_Decl : Node_Id;

      Element_Op : constant Entity_Id :=
                     Get_Iterable_Type_Primitive (Container_Typ, Name_Element);

      Advance   : Node_Id;
      Init      : Node_Id;
      New_Loop  : Node_Id;

   begin
      --  For an element iterator, the Element aspect must be present,
      --  (this is checked during analysis).

      --  We create a block to hold a variable declaration initialized with
      --  a call to Element, and generate:

      --    Cursor : Cursor_Type := First (Container);
      --    while Has_Element (Cursor, Container) loop
      --       declare
      --          Elmt : Element_Type := Element (Container, Cursor);
      --       begin
      --          <original loop statements>
      --          Cursor := Next (Container, Cursor);
      --       end;
      --    end loop;

      Build_Formal_Container_Iteration
        (N, Container, Cursor, Init, Advance, New_Loop);
      Append_To (Stats, Advance);

      Mutate_Ekind (Cursor, E_Variable);
      Insert_Action (N, Init);

      --  The loop parameter is declared by an object declaration, but within
      --  the loop we must prevent user assignments to it; the following flag
      --  accomplishes that.

      Set_Is_Loop_Parameter (Element);

      --  Declaration for Element

      Elmt_Decl :=
        Make_Object_Declaration (Loc,
          Defining_Identifier => Element,
          Object_Definition   => New_Occurrence_Of (Etype (Element_Op), Loc));

      Set_Expression (Elmt_Decl,
        Make_Function_Call (Loc,
          Name                   => New_Occurrence_Of (Element_Op, Loc),
          Parameter_Associations => New_List (
            Convert_To_Iterable_Type (Container, Loc),
            New_Occurrence_Of (Cursor, Loc))));

      Set_Statements (New_Loop,
        New_List
          (Make_Block_Statement (Loc,
             Declarations => New_List (Elmt_Decl),
             Handled_Statement_Sequence =>
               Make_Handled_Sequence_Of_Statements (Loc,
                 Statements => Stats))));

      --  The element is only modified in expanded code, so it appears as
      --  unassigned to the warning machinery. We must suppress this spurious
      --  warning explicitly.

      Set_Warnings_Off (Element);

      Rewrite (N, New_Loop);
      Analyze (N);
   end Expand_Formal_Container_Element_Loop;

   ----------------------------------
   -- Expand_N_Goto_When_Statement --
   ----------------------------------

   procedure Expand_N_Goto_When_Statement (N : Node_Id) is
      Loc : constant Source_Ptr := Sloc (N);
   begin
      Rewrite (N,
        Make_If_Statement (Loc,
          Condition       => Condition (N),
          Then_Statements => New_List (
            Make_Goto_Statement (Loc,
              Name => Name (N)))));

      Analyze (N);
   end Expand_N_Goto_When_Statement;

   ---------------------------
   -- Expand_N_If_Statement --
   ---------------------------

   --  First we deal with the case of C and Fortran convention boolean values,
   --  with zero/nonzero semantics.

   --  Second, we deal with the obvious rewriting for the cases where the
   --  condition of the IF is known at compile time to be True or False.

   --  Third, we remove elsif parts which have non-empty Condition_Actions and
   --  rewrite as independent if statements. For example:

   --     if x then xs
   --     elsif y then ys
   --     ...
   --     end if;

   --  becomes
   --
   --     if x then xs
   --     else
   --        <<condition actions of y>>
   --        if y then ys
   --        ...
   --        end if;
   --     end if;

   --  This rewriting is needed if at least one elsif part has a non-empty
   --  Condition_Actions list. We also do the same processing if there is a
   --  constant condition in an elsif part (in conjunction with the first
   --  processing step mentioned above, for the recursive call made to deal
   --  with the created inner if, this deals with properly optimizing the
   --  cases of constant elsif conditions).

   procedure Expand_N_If_Statement (N : Node_Id) is
      Loc    : constant Source_Ptr := Sloc (N);
      Hed    : Node_Id;
      E      : Node_Id;
      New_If : Node_Id;

      Warn_If_Deleted : constant Boolean :=
                          Warn_On_Deleted_Code and then Comes_From_Source (N);
      --  Indicates whether we want warnings when we delete branches of the
      --  if statement based on constant condition analysis. We never want
      --  these warnings for expander generated code.

   begin
      --  Do not consider controlled objects found in an if statement which
      --  actually models an if expression because their early finalization
      --  will affect the result of the expression.

      if not From_Conditional_Expression (N) then
         Process_Statements_For_Controlled_Objects (N);
      end if;

      Adjust_Condition (Condition (N));

      --  The following loop deals with constant conditions for the IF. We
      --  need a loop because as we eliminate False conditions, we grab the
      --  first elsif condition and use it as the primary condition.

      while Compile_Time_Known_Value (Condition (N)) loop

         --  If condition is True, we can simply rewrite the if statement now
         --  by replacing it by the series of then statements.

         if Is_True (Expr_Value (Condition (N))) then

            --  All the else parts can be killed

            Kill_Dead_Code (Elsif_Parts (N), Warn_If_Deleted);
            Kill_Dead_Code (Else_Statements (N), Warn_If_Deleted);

            Hed := Remove_Head (Then_Statements (N));
            Insert_List_After (N, Then_Statements (N));
            Rewrite (N, Hed);
            return;

         --  If condition is False, then we can delete the condition and
         --  the Then statements

         else
            --  We do not delete the condition if constant condition warnings
            --  are enabled, since otherwise we end up deleting the desired
            --  warning. Of course the backend will get rid of this True/False
            --  test anyway, so nothing is lost here.

            if not Constant_Condition_Warnings then
               Kill_Dead_Code (Condition (N));
            end if;

            Kill_Dead_Code (Then_Statements (N), Warn_If_Deleted);

            --  If there are no elsif statements, then we simply replace the
            --  entire if statement by the sequence of else statements.

            if No (Elsif_Parts (N)) then
               if No (Else_Statements (N))
                 or else Is_Empty_List (Else_Statements (N))
               then
                  Rewrite (N,
                    Make_Null_Statement (Sloc (N)));
               else
                  Hed := Remove_Head (Else_Statements (N));
                  Insert_List_After (N, Else_Statements (N));
                  Rewrite (N, Hed);
               end if;

               return;

            --  If there are elsif statements, the first of them becomes the
            --  if/then section of the rebuilt if statement This is the case
            --  where we loop to reprocess this copied condition.

            else
               Hed := Remove_Head (Elsif_Parts (N));
               Insert_Actions      (N, Condition_Actions (Hed));
               Set_Condition       (N, Condition (Hed));
               Set_Then_Statements (N, Then_Statements (Hed));

               --  Hed might have been captured as the condition determining
               --  the current value for an entity. Now it is detached from
               --  the tree, so a Current_Value pointer in the condition might
               --  need to be updated.

               Set_Current_Value_Condition (N);

               if Is_Empty_List (Elsif_Parts (N)) then
                  Set_Elsif_Parts (N, No_List);
               end if;
            end if;
         end if;
      end loop;

      --  Loop through elsif parts, dealing with constant conditions and
      --  possible condition actions that are present.

      if Present (Elsif_Parts (N)) then
         E := First (Elsif_Parts (N));
         while Present (E) loop

            --  Do not consider controlled objects found in an if statement
            --  which actually models an if expression because their early
            --  finalization will affect the result of the expression.

            if not From_Conditional_Expression (N) then
               Process_Statements_For_Controlled_Objects (E);
            end if;

            Adjust_Condition (Condition (E));

            --  If there are condition actions, then rewrite the if statement
            --  as indicated above. We also do the same rewrite for a True or
            --  False condition. The further processing of this constant
            --  condition is then done by the recursive call to expand the
            --  newly created if statement

            if Present (Condition_Actions (E))
              or else Compile_Time_Known_Value (Condition (E))
            then
               New_If :=
                 Make_If_Statement (Sloc (E),
                   Condition       => Condition (E),
                   Then_Statements => Then_Statements (E),
                   Elsif_Parts     => No_List,
                   Else_Statements => Else_Statements (N));

               --  Elsif parts for new if come from remaining elsif's of parent

               while Present (Next (E)) loop
                  if No (Elsif_Parts (New_If)) then
                     Set_Elsif_Parts (New_If, New_List);
                  end if;

                  Append (Remove_Next (E), Elsif_Parts (New_If));
               end loop;

               Set_Else_Statements (N, New_List (New_If));

               if Present (Condition_Actions (E)) then
                  Insert_List_Before (New_If, Condition_Actions (E));
               end if;

               Remove (E);

               if Is_Empty_List (Elsif_Parts (N)) then
                  Set_Elsif_Parts (N, No_List);
               end if;

               Analyze (New_If);

               --  Note this is not an implicit if statement, since it is part
               --  of an explicit if statement in the source (or of an implicit
               --  if statement that has already been tested). We set the flag
               --  after calling Analyze to avoid generating extra warnings
               --  specific to pure if statements, however (see
               --  Sem_Ch5.Analyze_If_Statement).

               Preserve_Comes_From_Source (New_If, N);
               return;

            --  No special processing for that elsif part, move to next

            else
               Next (E);
            end if;
         end loop;
      end if;

      --  Some more optimizations applicable if we still have an IF statement

      if Nkind (N) /= N_If_Statement then
         return;
      end if;

      --  Another optimization, special cases that can be simplified

      --     if expression then
      --        return [standard.]true;
      --     else
      --        return [standard.]false;
      --     end if;

      --  can be changed to:

      --     return expression;

      --  and

      --     if expression then
      --        return [standard.]false;
      --     else
      --        return [standard.]true;
      --     end if;

      --  can be changed to:

      --     return not (expression);

      --  Do these optimizations only for internally generated code and only
      --  when -fpreserve-control-flow isn't set, to preserve the original
      --  source control flow.

      if not Comes_From_Source (N)
        and then not Opt.Suppress_Control_Flow_Optimizations
        and then Nkind (N) = N_If_Statement
        and then No (Elsif_Parts (N))
        and then Present (Else_Statements (N))
        and then List_Length (Then_Statements (N)) = 1
        and then List_Length (Else_Statements (N)) = 1
      then
         declare
            Then_Stm : constant Node_Id := First (Then_Statements (N));
            Else_Stm : constant Node_Id := First (Else_Statements (N));

            Then_Expr : Node_Id;
            Else_Expr : Node_Id;

         begin
            if Nkind (Then_Stm) = N_Simple_Return_Statement
                 and then
               Nkind (Else_Stm) = N_Simple_Return_Statement
            then
               Then_Expr := Expression (Then_Stm);
               Else_Expr := Expression (Else_Stm);

               if Nkind (Then_Expr) in N_Expanded_Name | N_Identifier
                    and then
                  Nkind (Else_Expr) in N_Expanded_Name | N_Identifier
               then
                  if Entity (Then_Expr) = Standard_True
                    and then Entity (Else_Expr) = Standard_False
                  then
                     Rewrite (N,
                       Make_Simple_Return_Statement (Loc,
                         Expression => Relocate_Node (Condition (N))));
                     Analyze (N);

                  elsif Entity (Then_Expr) = Standard_False
                    and then Entity (Else_Expr) = Standard_True
                  then
                     Rewrite (N,
                       Make_Simple_Return_Statement (Loc,
                         Expression =>
                           Make_Op_Not (Loc,
                             Right_Opnd => Relocate_Node (Condition (N)))));
                     Analyze (N);
                  end if;
               end if;
            end if;
         end;
      end if;
   end Expand_N_If_Statement;

   --------------------------
   -- Expand_Iterator_Loop --
   --------------------------

   procedure Expand_Iterator_Loop (N : Node_Id) is
      Isc    : constant Node_Id    := Iteration_Scheme (N);
      I_Spec : constant Node_Id    := Iterator_Specification (Isc);

      Container     : constant Node_Id     := Name (I_Spec);
      Container_Typ : constant Entity_Id   := Base_Type (Etype (Container));

   begin
      --  Processing for arrays

      if Is_Array_Type (Container_Typ) then
         pragma Assert (Of_Present (I_Spec));
         Expand_Iterator_Loop_Over_Array (N);

      elsif Has_Aspect (Container_Typ, Aspect_Iterable) then
         if Of_Present (I_Spec) then
            Expand_Formal_Container_Element_Loop (N);
         else
            Expand_Formal_Container_Loop (N);
         end if;

      --  Processing for containers

      else
         Expand_Iterator_Loop_Over_Container
           (N, Isc, I_Spec, Container, Container_Typ);
      end if;
   end Expand_Iterator_Loop;

   -------------------------------------
   -- Expand_Iterator_Loop_Over_Array --
   -------------------------------------

   procedure Expand_Iterator_Loop_Over_Array (N : Node_Id) is
      Isc        : constant Node_Id    := Iteration_Scheme (N);
      I_Spec     : constant Node_Id    := Iterator_Specification (Isc);
      Array_Node : constant Node_Id    := Name (I_Spec);
      Array_Typ  : constant Entity_Id  := Base_Type (Etype (Array_Node));
      Array_Dim  : constant Pos        := Number_Dimensions (Array_Typ);
      Id         : constant Entity_Id  := Defining_Identifier (I_Spec);
      Loc        : constant Source_Ptr := Sloc (Isc);
      Stats      : List_Id    := Statements (N);
      Core_Loop  : Node_Id;
      Dim1       : Int;
      Ind_Comp   : Node_Id;
      Iterator   : Entity_Id;

   begin
      if Present (Iterator_Filter (I_Spec)) then
         pragma Assert (Ada_Version >= Ada_2022);
         Stats := New_List (Make_If_Statement (Loc,
            Condition => Iterator_Filter (I_Spec),
            Then_Statements => Stats));
      end if;

      --  for Element of Array loop

      --  It requires an internally generated cursor to iterate over the array

      pragma Assert (Of_Present (I_Spec));

      Iterator := Make_Temporary (Loc, 'C');

      --  Generate:
      --    Element : Component_Type renames Array (Iterator);
      --    Iterator is the index value, or a list of index values
      --    in the case of a multidimensional array.

      Ind_Comp :=
        Make_Indexed_Component (Loc,
          Prefix      => New_Copy_Tree (Array_Node),
          Expressions => New_List (New_Occurrence_Of (Iterator, Loc)));

      --  Propagate the original node to the copy since the analysis of the
      --  following object renaming declaration relies on the original node.

      Set_Original_Node (Prefix (Ind_Comp), Original_Node (Array_Node));

      Prepend_To (Stats,
        Make_Object_Renaming_Declaration (Loc,
          Defining_Identifier => Id,
          Subtype_Mark        =>
            New_Occurrence_Of (Component_Type (Array_Typ), Loc),
          Name                => Ind_Comp));

      --  Mark the loop variable as needing debug info, so that expansion
      --  of the renaming will result in Materialize_Entity getting set via
      --  Debug_Renaming_Declaration. (This setting is needed here because
      --  the setting in Freeze_Entity comes after the expansion, which is
      --  too late. ???)

      Set_Debug_Info_Needed (Id);

      --  Generate:

      --    for Iterator in [reverse] Array'Range (Array_Dim) loop
      --       Element : Component_Type renames Array (Iterator);
      --       <original loop statements>
      --    end loop;

      --  If this is an iteration over a multidimensional array, the
      --  innermost loop is over the last dimension in Ada, and over
      --  the first dimension in Fortran.

      if Convention (Array_Typ) = Convention_Fortran then
         Dim1 := 1;
      else
         Dim1 := Array_Dim;
      end if;

      Core_Loop :=
        Make_Loop_Statement (Sloc (N),
          Iteration_Scheme =>
            Make_Iteration_Scheme (Loc,
              Loop_Parameter_Specification =>
                Make_Loop_Parameter_Specification (Loc,
                  Defining_Identifier         => Iterator,
                  Discrete_Subtype_Definition =>
                    Make_Attribute_Reference (Loc,
                      Prefix         => New_Copy_Tree (Array_Node),
                      Attribute_Name => Name_Range,
                      Expressions    => New_List (
                        Make_Integer_Literal (Loc, Dim1))),
                  Reverse_Present             => Reverse_Present (I_Spec))),
           Statements      => Stats,
           End_Label       => Empty);

      --  Processing for multidimensional array. The body of each loop is
      --  a loop over a previous dimension, going in decreasing order in Ada
      --  and in increasing order in Fortran.

      if Array_Dim > 1 then
         for Dim in 1 .. Array_Dim - 1 loop
            if Convention (Array_Typ) = Convention_Fortran then
               Dim1 := Dim + 1;
            else
               Dim1 := Array_Dim - Dim;
            end if;

            Iterator := Make_Temporary (Loc, 'C');

            --  Generate the dimension loops starting from the innermost one

            --    for Iterator in [reverse] Array'Range (Array_Dim - Dim) loop
            --       <core loop>
            --    end loop;

            Core_Loop :=
              Make_Loop_Statement (Sloc (N),
                Iteration_Scheme =>
                  Make_Iteration_Scheme (Loc,
                    Loop_Parameter_Specification =>
                      Make_Loop_Parameter_Specification (Loc,
                        Defining_Identifier         => Iterator,
                        Discrete_Subtype_Definition =>
                          Make_Attribute_Reference (Loc,
                            Prefix         => New_Copy_Tree (Array_Node),
                            Attribute_Name => Name_Range,
                            Expressions    => New_List (
                              Make_Integer_Literal (Loc, Dim1))),
                    Reverse_Present              => Reverse_Present (I_Spec))),
                Statements       => New_List (Core_Loop),
                End_Label        => Empty);

            --  Update the previously created object renaming declaration with
            --  the new iterator, by adding the index of the next loop to the
            --  indexed component, in the order that corresponds to the
            --  convention.

            if Convention (Array_Typ) = Convention_Fortran then
               Append_To (Expressions (Ind_Comp),
                 New_Occurrence_Of (Iterator, Loc));
            else
               Prepend_To (Expressions (Ind_Comp),
                 New_Occurrence_Of (Iterator, Loc));
            end if;
         end loop;
      end if;

      --  Inherit the loop identifier from the original loop. This ensures that
      --  the scope stack is consistent after the rewriting.

      if Present (Identifier (N)) then
         Set_Identifier (Core_Loop, Relocate_Node (Identifier (N)));
      end if;

      Rewrite (N, Core_Loop);
      Analyze (N);
   end Expand_Iterator_Loop_Over_Array;

   -----------------------------------------
   -- Expand_Iterator_Loop_Over_Container --
   -----------------------------------------

   --  For a 'for ... in' loop, such as:

   --      for Cursor in Iterator_Function (...) loop
   --          ...
   --      end loop;

   --  we generate:

   --    Iter : Iterator_Type := Iterator_Function (...);
   --    Cursor : Cursor_type := First (Iter); -- or Last for "reverse"
   --    while Has_Element (Cursor) loop
   --       ...
   --
   --       Cursor := Iter.Next (Cursor); -- or Prev for "reverse"
   --    end loop;

   --  For a 'for ... of' loop, such as:

   --      for X of Container loop
   --          ...
   --      end loop;

   --  the RM implies the generation of:

   --    Iter : Iterator_Type := Container.Iterate; -- the Default_Iterator
   --    Cursor : Cursor_Type := First (Iter); -- or Last for "reverse"
   --    while Has_Element (Cursor) loop
   --       declare
   --          X : Element_Type renames Element (Cursor).Element.all;
   --          --  or Constant_Element
   --       begin
   --          ...
   --       end;
   --       Cursor := Iter.Next (Cursor); -- or Prev for "reverse"
   --    end loop;

   --  In the general case, we do what the RM says. However, the operations
   --  Element and Iter.Next are slow, which is bad inside a loop, because they
   --  involve dispatching via interfaces, secondary stack manipulation,
   --  Busy/Lock incr/decr, and adjust/finalization/at-end handling. So for the
   --  predefined containers, we use an equivalent but optimized expansion.

   --  In the optimized case, we make use of these:

   --     procedure Next (Position : in out Cursor); -- instead of Iter.Next

   --     function Pseudo_Reference
   --       (Container : aliased Vector'Class) return Reference_Control_Type;

   --     type Element_Access is access all Element_Type;

   --     function Get_Element_Access
   --       (Position : Cursor) return not null Element_Access;

   --  Next is declared in the visible part of the container packages.
   --  The other three are added in the private part. (We're not supposed to
   --  pollute the namespace for clients. The compiler has no trouble breaking
   --  privacy to call things in the private part of an instance.)

   --  Source:

   --      for X of My_Vector loop
   --          X.Count := X.Count + 1;
   --          ...
   --      end loop;

   --  The compiler will generate:

   --      Iter : Reversible_Iterator'Class := Iterate (My_Vector);
   --      --  Reversible_Iterator is an interface. Iterate is the
   --      --  Default_Iterator aspect of Vector. This increments Lock,
   --      --  disallowing tampering with cursors. Unfortunately, it does not
   --      --  increment Busy. The result of Iterate is Limited_Controlled;
   --      --  finalization will decrement Lock. This is a build-in-place
   --      --  dispatching call to Iterate.

   --      Cur : Cursor := First (Iter); -- or Last
   --      --  Dispatching call via interface.

   --      Control : Reference_Control_Type := Pseudo_Reference (My_Vector);
   --      --  Pseudo_Reference increments Busy, to detect tampering with
   --      --  elements, as required by RM. Also redundantly increment
   --      --  Lock. Finalization of Control will decrement both Busy and
   --      --  Lock. Pseudo_Reference returns a record containing a pointer to
   --      --  My_Vector, used by Finalize.
   --      --
   --      --  Control is not used below, except to finalize it -- it's purely
   --      --  an RAII thing. This is needed because we are eliminating the
   --      --  call to Reference within the loop.

   --      while Has_Element (Cur) loop
   --          declare
   --              X : My_Element renames Get_Element_Access (Cur).all;
   --              --  Get_Element_Access returns a pointer to the element
   --              --  designated by Cur. No dispatching here, and no horsing
   --              --  around with access discriminants. This is instead of the
   --              --  existing
   --              --
   --              --    X : My_Element renames Reference (Cur).Element.all;
   --              --
   --              --  which creates a controlled object.
   --          begin
   --              --  Any attempt to tamper with My_Vector here in the loop
   --              --  will correctly raise Program_Error, because of the
   --              --  Control.
   --
   --              X.Count := X.Count + 1;
   --              ...
   --
   --              Next (Cur); -- or Prev
   --              --  This is instead of "Cur := Next (Iter, Cur);"
   --          end;
   --          --  No finalization here
   --      end loop;
   --      Finalize Iter and Control here, decrementing Lock twice and Busy
   --      once.

   --  This optimization makes "for ... of" loops over 30 times faster in cases
   --  measured.

   procedure Expand_Iterator_Loop_Over_Container
     (N             : Node_Id;
      Isc           : Node_Id;
      I_Spec        : Node_Id;
      Container     : Node_Id;
      Container_Typ : Entity_Id)
   is
      Id       : constant Entity_Id   := Defining_Identifier (I_Spec);
      Elem_Typ : constant Entity_Id   := Etype (Id);
      Id_Kind  : constant Entity_Kind := Ekind (Id);
      Loc      : constant Source_Ptr  := Sloc (N);

      Stats    : List_Id     := Statements (N);
      --  Maybe wrapped in a conditional if a filter is present

      Cursor    : Entity_Id;
      Decl      : Node_Id;
      Iter_Type : Entity_Id;
      Iterator  : Entity_Id;
      Name_Init : Name_Id;
      Name_Step : Name_Id;
      New_Loop  : Node_Id;

      Fast_Element_Access_Op : Entity_Id := Empty;
      Fast_Step_Op           : Entity_Id := Empty;
      --  Only for optimized version of "for ... of"

      Iter_Pack : Entity_Id;
      --  The package in which the iterator interface is instantiated. This is
      --  typically an instance within the container package.

      Pack : Entity_Id;
      --  The package in which the container type is declared

   begin
      if Present (Iterator_Filter (I_Spec)) then
         pragma Assert (Ada_Version >= Ada_2022);
         Stats := New_List (Make_If_Statement (Loc,
            Condition => Iterator_Filter (I_Spec),
            Then_Statements => Stats));
      end if;

      --  Determine the advancement and initialization steps for the cursor.
      --  Analysis of the expanded loop will verify that the container has a
      --  reverse iterator.

      if Reverse_Present (I_Spec) then
         Name_Init := Name_Last;
         Name_Step := Name_Previous;
      else
         Name_Init := Name_First;
         Name_Step := Name_Next;
      end if;

      --  The type of the iterator is the return type of the Iterate function
      --  used. For the "of" form this is the default iterator for the type,
      --  otherwise it is the type of the explicit function used in the
      --  iterator specification. The most common case will be an Iterate
      --  function in the container package.

      --  The Iterator type is declared in an instance within the container
      --  package itself, for example:

      --    package Vector_Iterator_Interfaces is new
      --      Ada.Iterator_Interfaces (Cursor, Has_Element);

      --  If the container type is a derived type, the cursor type is found in
      --  the package of the ultimate ancestor type.

      if Is_Derived_Type (Container_Typ) then
         Pack := Scope (Root_Type (Container_Typ));
      else
         Pack := Scope (Container_Typ);
      end if;

      if Of_Present (I_Spec) then
         Handle_Of : declare
            Container_Arg : Node_Id;

            function Get_Default_Iterator
              (T : Entity_Id) return Entity_Id;
            --  Return the default iterator for a specific type. If the type is
            --  derived, we return the inherited or overridden one if
            --  appropriate.

            --------------------------
            -- Get_Default_Iterator --
            --------------------------

            function Get_Default_Iterator
              (T : Entity_Id) return Entity_Id
            is
               Iter : constant Entity_Id :=
                 Entity (Find_Value_Of_Aspect (T, Aspect_Default_Iterator));
               Prim : Elmt_Id;
               Op   : Entity_Id;

            begin
               Container_Arg := New_Copy_Tree (Container);

               --  A previous version of GNAT allowed indexing aspects to be
               --  redefined on derived container types, while the default
               --  iterator was inherited from the parent type. This
               --  nonstandard extension is preserved for use by the
               --  modeling project under debug flag -gnatd.X.

               if Debug_Flag_Dot_XX then
                  if Base_Type (Etype (Container)) /=
                     Base_Type (Etype (First_Formal (Iter)))
                  then
                     Container_Arg :=
                       Make_Type_Conversion (Loc,
                         Subtype_Mark =>
                           New_Occurrence_Of
                             (Etype (First_Formal (Iter)), Loc),
                         Expression   => Container_Arg);
                  end if;

                  return Iter;

               elsif Is_Derived_Type (T) then

                  --  The default iterator must be a primitive operation of the
                  --  type, at the same dispatch slot position. The DT position
                  --  may not be established if type is not frozen yet.

                  Prim := First_Elmt (Primitive_Operations (T));
                  while Present (Prim) loop
                     Op := Node (Prim);

                     if Alias (Op) = Iter
                       or else
                         (Chars (Op) = Chars (Iter)
                           and then Present (DTC_Entity (Op))
                           and then DT_Position (Op) = DT_Position (Iter))
                     then
                        return Op;
                     end if;

                     Next_Elmt (Prim);
                  end loop;

                  --  If we didn't find it, then our parent type is not
                  --  iterable, so we return the Default_Iterator aspect of
                  --  this type.

                  return Iter;

               --  Otherwise not a derived type

               else
                  return Iter;
               end if;
            end Get_Default_Iterator;

            --  Local variables

            Default_Iter : Entity_Id;
            Ent          : Entity_Id;

            Reference_Control_Type : Entity_Id := Empty;
            Pseudo_Reference       : Entity_Id := Empty;

         --  Start of processing for Handle_Of

         begin
            if Is_Class_Wide_Type (Container_Typ) then
               Default_Iter :=
                 Get_Default_Iterator (Etype (Base_Type (Container_Typ)));
            else
               Default_Iter := Get_Default_Iterator (Etype (Container));
            end if;

            Cursor := Make_Temporary (Loc, 'C');

            --  For a container element iterator, the iterator type is obtained
            --  from the corresponding aspect, whose return type is descended
            --  from the corresponding interface type in some instance of
            --  Ada.Iterator_Interfaces. The actuals of that instantiation
            --  are Cursor and Has_Element.

            Iter_Type := Etype (Default_Iter);

            --  The iterator type, which is a class-wide type, may itself be
            --  derived locally, so the desired instantiation is the scope of
            --  the root type of the iterator type.

            Iter_Pack := Scope (Root_Type (Etype (Iter_Type)));

            --  Find declarations needed for "for ... of" optimization
            --  These declarations come from GNAT sources or sources
            --  derived from them. User code may include additional
            --  overloadings with similar names, and we need to perforn
            --  some reasonable resolution to find the needed primitives.
            --  It is unclear whether this mechanism is fragile if a user
            --  makes arbitrary changes to the private part of a package
            --  that supports iterators.

            Ent := First_Entity (Pack);
            while Present (Ent) loop
               if Chars (Ent) = Name_Get_Element_Access
                 and then Present (First_Formal (Ent))
                 and then Chars (First_Formal (Ent)) = Name_Position
                 and then No (Next_Formal (First_Formal (Ent)))
               then
                  Fast_Element_Access_Op := Ent;

               elsif Chars (Ent) = Name_Step
                 and then Ekind (Ent) = E_Procedure
               then
                  Fast_Step_Op := Ent;

               elsif Chars (Ent) = Name_Reference_Control_Type then
                  Reference_Control_Type := Ent;

               elsif Chars (Ent) = Name_Pseudo_Reference then
                  Pseudo_Reference := Ent;
               end if;

               Next_Entity (Ent);
            end loop;

            if Present (Reference_Control_Type)
              and then Present (Pseudo_Reference)
            then
               Insert_Action (N,
                 Make_Object_Declaration (Loc,
                   Defining_Identifier => Make_Temporary (Loc, 'D'),
                   Object_Definition   =>
                     New_Occurrence_Of (Reference_Control_Type, Loc),
                   Expression          =>
                     Make_Function_Call (Loc,
                       Name                   =>
                         New_Occurrence_Of (Pseudo_Reference, Loc),
                       Parameter_Associations =>
                         New_List (New_Copy_Tree (Container_Arg)))));
            end if;

            --  Rewrite domain of iteration as a call to the default iterator
            --  for the container type. The formal may be an access parameter
            --  in which case we must build a reference to the container.

            declare
               Arg : Node_Id;
            begin
               if Is_Access_Type (Etype (First_Entity (Default_Iter))) then
                  Arg :=
                    Make_Attribute_Reference (Loc,
                      Prefix         => Container_Arg,
                      Attribute_Name => Name_Unrestricted_Access);
               else
                  Arg := Container_Arg;
               end if;

               Rewrite (Name (I_Spec),
                 Make_Function_Call (Loc,
                   Name                   =>
                     New_Occurrence_Of (Default_Iter, Loc),
                   Parameter_Associations => New_List (Arg)));
            end;

            Analyze_And_Resolve (Name (I_Spec));

            --  Find cursor type in proper iterator package, which is an
            --  instantiation of Iterator_Interfaces.

            Ent := First_Entity (Iter_Pack);
            while Present (Ent) loop
               if Chars (Ent) = Name_Cursor then
                  Set_Etype (Cursor, Etype (Ent));
                  exit;
               end if;

               Next_Entity (Ent);
            end loop;

            if Present (Fast_Element_Access_Op) then
               Decl :=
                 Make_Object_Renaming_Declaration (Loc,
                   Defining_Identifier => Id,
                   Subtype_Mark        =>
                     New_Occurrence_Of (Elem_Typ, Loc),
                   Name                =>
                     Make_Explicit_Dereference (Loc,
                       Prefix =>
                         Make_Function_Call (Loc,
                           Name                   =>
                             New_Occurrence_Of (Fast_Element_Access_Op, Loc),
                           Parameter_Associations =>
                             New_List (New_Occurrence_Of (Cursor, Loc)))));

            else
               Decl :=
                 Make_Object_Renaming_Declaration (Loc,
                   Defining_Identifier => Id,
                   Subtype_Mark        =>
                     New_Occurrence_Of (Elem_Typ, Loc),
                   Name                =>
                     Make_Indexed_Component (Loc,
                       Prefix      => Relocate_Node (Container_Arg),
                       Expressions =>
                         New_List (New_Occurrence_Of (Cursor, Loc))));
            end if;

            --  The defining identifier in the iterator is user-visible and
            --  must be visible in the debugger.

            Set_Debug_Info_Needed (Id);

            --  If the container does not have a variable indexing aspect,
            --  the element is a constant in the loop. The container itself
            --  may be constant, in which case the element is a constant as
            --  well. The container has been rewritten as a call to Iterate,
            --  so examine original node.

            if No (Find_Value_Of_Aspect
                     (Container_Typ, Aspect_Variable_Indexing))
              or else not Is_Variable (Original_Node (Container))
            then
               Mutate_Ekind (Id, E_Constant);
            end if;

            Prepend_To (Stats, Decl);
         end Handle_Of;

      --  X in Iterate (S) : type of iterator is type of explicitly given
      --  Iterate function, and the loop variable is the cursor. It will be
      --  assigned in the loop and must be a variable.

      else
         Iter_Type := Etype (Name (I_Spec));

         --  The iterator type, which is a class-wide type, may itself be
         --  derived locally, so the desired instantiation is the scope of
         --  the root type of the iterator type, as in the "of" case.

         Iter_Pack := Scope (Root_Type (Etype (Iter_Type)));
         Cursor := Id;
      end if;

      Iterator := Make_Temporary (Loc, 'I');

      --  For both iterator forms, add a call to the step operation to advance
      --  the cursor. Generate:

      --     Cursor := Iterator.Next (Cursor);

      --   or else

      --     Cursor := Next (Cursor);

      if Present (Fast_Element_Access_Op) and then Present (Fast_Step_Op) then
         declare
            Curs_Name : constant Node_Id := New_Occurrence_Of (Cursor, Loc);
            Step_Call : Node_Id;

         begin
            Step_Call :=
              Make_Procedure_Call_Statement (Loc,
                Name                   =>
                  New_Occurrence_Of (Fast_Step_Op, Loc),
                Parameter_Associations => New_List (Curs_Name));

            Append_To (Stats, Step_Call);
            Set_Assignment_OK (Curs_Name);
         end;

      else
         declare
            Rhs : Node_Id;

         begin
            Rhs :=
              Make_Function_Call (Loc,
                Name                   =>
                  Make_Selected_Component (Loc,
                    Prefix        => New_Occurrence_Of (Iterator, Loc),
                    Selector_Name => Make_Identifier (Loc, Name_Step)),
                Parameter_Associations => New_List (
                   New_Occurrence_Of (Cursor, Loc)));

            Append_To (Stats,
              Make_Assignment_Statement (Loc,
                 Name       => New_Occurrence_Of (Cursor, Loc),
                 Expression => Rhs));
            Set_Assignment_OK (Name (Last (Stats)));
         end;
      end if;

      --  Generate:
      --    while Has_Element (Cursor) loop
      --       <Stats>
      --    end loop;

      --   Has_Element is the second actual in the iterator package

      New_Loop :=
        Make_Loop_Statement (Loc,
          Iteration_Scheme =>
            Make_Iteration_Scheme (Loc,
              Condition =>
                Make_Function_Call (Loc,
                  Name                   =>
                    New_Occurrence_Of
                      (Next_Entity (First_Entity (Iter_Pack)), Loc),
                  Parameter_Associations => New_List (
                    New_Occurrence_Of (Cursor, Loc)))),

          Statements => Stats,
          End_Label  => Empty);

      --  If present, preserve identifier of loop, which can be used in an exit
      --  statement in the body.

      if Present (Identifier (N)) then
         Set_Identifier (New_Loop, Relocate_Node (Identifier (N)));
      end if;

      --  Create the declarations for Iterator and cursor and insert them
      --  before the source loop. Given that the domain of iteration is already
      --  an entity, the iterator is just a renaming of that entity. Possible
      --  optimization ???

      Insert_Action (N,
        Make_Object_Renaming_Declaration (Loc,
          Defining_Identifier => Iterator,
          Subtype_Mark        => New_Occurrence_Of (Iter_Type, Loc),
          Name                => Relocate_Node (Name (I_Spec))));

      --  Create declaration for cursor

      declare
         Cursor_Decl : constant Node_Id :=
                         Make_Object_Declaration (Loc,
                           Defining_Identifier => Cursor,
                           Object_Definition   =>
                             New_Occurrence_Of (Etype (Cursor), Loc),
                           Expression          =>
                             Make_Selected_Component (Loc,
                               Prefix        =>
                                 New_Occurrence_Of (Iterator, Loc),
                               Selector_Name =>
                                 Make_Identifier (Loc, Name_Init)));

      begin
         --  The cursor is only modified in expanded code, so it appears
         --  as unassigned to the warning machinery. We must suppress this
         --  spurious warning explicitly. The cursor's kind is that of the
         --  original loop parameter (it is a constant if the domain of
         --  iteration is constant).

         Set_Warnings_Off (Cursor);
         Set_Assignment_OK (Cursor_Decl);

         Insert_Action (N, Cursor_Decl);
         Mutate_Ekind (Cursor, Id_Kind);
      end;

      --  If the range of iteration is given by a function call that returns
      --  a container, the finalization actions have been saved in the
      --  Condition_Actions of the iterator. Insert them now at the head of
      --  the loop.

      if Present (Condition_Actions (Isc)) then
         Insert_List_Before (N, Condition_Actions (Isc));
      end if;

      Rewrite (N, New_Loop);
      Analyze (N);
   end Expand_Iterator_Loop_Over_Container;

   -----------------------------
   -- Expand_N_Loop_Statement --
   -----------------------------

   --  1. Remove null loop entirely
   --  2. Deal with while condition for C/Fortran boolean
   --  3. Deal with loops with a non-standard enumeration type range
   --  4. Deal with while loops where Condition_Actions is set
   --  5. Deal with loops over predicated subtypes
   --  6. Deal with loops with iterators over arrays and containers

   procedure Expand_N_Loop_Statement (N : Node_Id) is
      Loc    : constant Source_Ptr := Sloc (N);
      Scheme : constant Node_Id    := Iteration_Scheme (N);
      Stmt   : Node_Id;

   begin
      --  Delete null loop

      if Is_Null_Loop (N) then
         Rewrite (N, Make_Null_Statement (Loc));
         return;
      end if;

      --  Deal with condition for C/Fortran Boolean

      if Present (Scheme) then
         Adjust_Condition (Condition (Scheme));
      end if;

      --  Nothing more to do for plain loop with no iteration scheme

      if No (Scheme) then
         null;

      --  Case of for loop (Loop_Parameter_Specification present)

      --  Note: we do not have to worry about validity checking of the for loop
      --  range bounds here, since they were frozen with constant declarations
      --  and it is during that process that the validity checking is done.

      elsif Present (Loop_Parameter_Specification (Scheme)) then
         declare
            LPS     : constant Node_Id   :=
                        Loop_Parameter_Specification (Scheme);
            Loop_Id : constant Entity_Id := Defining_Identifier (LPS);
            Ltype   : constant Entity_Id := Etype (Loop_Id);
            Btype   : constant Entity_Id := Base_Type (Ltype);
            Stats   : constant List_Id   := Statements (N);
            Expr    : Node_Id;
            Decls   : List_Id;
            New_Id  : Entity_Id;

         begin
            --  If Discrete_Subtype_Definition has been rewritten as an
            --  N_Raise_xxx_Error, rewrite the whole loop as a raise node to
            --  avoid confusing the code generator down the line.

            if Nkind (Discrete_Subtype_Definition (LPS)) in N_Raise_xxx_Error
            then
               Rewrite (N, Discrete_Subtype_Definition (LPS));
               return;
            end if;

            if Present (Iterator_Filter (LPS)) then
               pragma Assert (Ada_Version >= Ada_2022);
               Set_Statements (N,
                  New_List (Make_If_Statement (Loc,
                    Condition => Iterator_Filter (LPS),
                    Then_Statements => Stats)));
            end if;

            --  Deal with loop over predicates

            if Is_Discrete_Type (Ltype)
              and then Present (Predicate_Function (Ltype))
            then
               Expand_Predicated_Loop (N);

            --  Handle the case where we have a for loop with the range type
            --  being an enumeration type with non-standard representation.
            --  In this case we expand:

            --    for x in [reverse] a .. b loop
            --       ...
            --    end loop;

            --  to

            --    for xP in [reverse] integer
            --      range etype'Pos (a) .. etype'Pos (b)
            --    loop
            --       declare
            --          x : constant etype := Pos_To_Rep (xP);
            --       begin
            --          ...
            --       end;
            --    end loop;

            elsif Is_Enumeration_Type (Btype)
              and then Present (Enum_Pos_To_Rep (Btype))
            then
               New_Id :=
                 Make_Defining_Identifier (Loc,
                   Chars => New_External_Name (Chars (Loop_Id), 'P'));

               --  If the type has a contiguous representation, successive
               --  values can be generated as offsets from the first literal.

               if Has_Contiguous_Rep (Btype) then
                  Expr :=
                     Unchecked_Convert_To (Btype,
                       Make_Op_Add (Loc,
                         Left_Opnd =>
                            Make_Integer_Literal (Loc,
                              Enumeration_Rep (First_Literal (Btype))),
                         Right_Opnd => New_Occurrence_Of (New_Id, Loc)));
               else
                  --  Use the constructed array Enum_Pos_To_Rep

                  Expr :=
                    Make_Indexed_Component (Loc,
                      Prefix      =>
                        New_Occurrence_Of (Enum_Pos_To_Rep (Btype), Loc),
                      Expressions =>
                        New_List (New_Occurrence_Of (New_Id, Loc)));
               end if;

               --  Build declaration for loop identifier

               Decls :=
                 New_List (
                   Make_Object_Declaration (Loc,
                     Defining_Identifier => Loop_Id,
                     Constant_Present    => True,
                     Object_Definition   => New_Occurrence_Of (Ltype, Loc),
                     Expression          => Expr));

               Rewrite (N,
                 Make_Loop_Statement (Loc,
                   Identifier => Identifier (N),

                   Iteration_Scheme =>
                     Make_Iteration_Scheme (Loc,
                       Loop_Parameter_Specification =>
                         Make_Loop_Parameter_Specification (Loc,
                           Defining_Identifier => New_Id,
                           Reverse_Present => Reverse_Present (LPS),

                           Discrete_Subtype_Definition =>
                             Make_Subtype_Indication (Loc,

                               Subtype_Mark =>
                                 New_Occurrence_Of (Standard_Natural, Loc),

                               Constraint =>
                                 Make_Range_Constraint (Loc,
                                   Range_Expression =>
                                     Make_Range (Loc,

                                       Low_Bound =>
                                         Make_Attribute_Reference (Loc,
                                           Prefix =>
                                             New_Occurrence_Of (Btype, Loc),

                                           Attribute_Name => Name_Pos,

                                           Expressions => New_List (
                                             Relocate_Node
                                               (Type_Low_Bound (Ltype)))),

                                       High_Bound =>
                                         Make_Attribute_Reference (Loc,
                                           Prefix =>
                                             New_Occurrence_Of (Btype, Loc),

                                           Attribute_Name => Name_Pos,

                                           Expressions => New_List (
                                             Relocate_Node
                                               (Type_High_Bound
                                                  (Ltype))))))))),

                   Statements => New_List (
                     Make_Block_Statement (Loc,
                       Declarations => Decls,
                       Handled_Statement_Sequence =>
                         Make_Handled_Sequence_Of_Statements (Loc,
                           Statements => Stats))),

                   End_Label => End_Label (N)));

               --  The loop parameter's entity must be removed from the loop
               --  scope's entity list and rendered invisible, since it will
               --  now be located in the new block scope. Any other entities
               --  already associated with the loop scope, such as the loop
               --  parameter's subtype, will remain there.

               --  In an element loop, the loop will contain a declaration for
               --  a cursor variable; otherwise the loop id is the first entity
               --  in the scope constructed for the loop.

               if Comes_From_Source (Loop_Id) then
                  pragma Assert (First_Entity (Scope (Loop_Id)) = Loop_Id);
                  null;
               end if;

               Set_First_Entity (Scope (Loop_Id), Next_Entity (Loop_Id));
               Remove_Homonym (Loop_Id);

               if Last_Entity (Scope (Loop_Id)) = Loop_Id then
                  Set_Last_Entity (Scope (Loop_Id), Empty);
               end if;

               Analyze (N);

            --  Nothing to do with other cases of for loops

            else
               null;
            end if;
         end;

      --  Second case, if we have a while loop with Condition_Actions set, then
      --  we change it into a plain loop:

      --    while C loop
      --       ...
      --    end loop;

      --  changed to:

      --    loop
      --       <<condition actions>>
      --       exit when not C;
      --       ...
      --    end loop

      elsif Present (Scheme)
        and then Present (Condition_Actions (Scheme))
        and then Present (Condition (Scheme))
      then
         declare
            ES : Node_Id;

         begin
            ES :=
              Make_Exit_Statement (Sloc (Condition (Scheme)),
                Condition =>
                  Make_Op_Not (Sloc (Condition (Scheme)),
                    Right_Opnd => Condition (Scheme)));

            Prepend (ES, Statements (N));
            Insert_List_Before (ES, Condition_Actions (Scheme));

            --  This is not an implicit loop, since it is generated in response
            --  to the loop statement being processed. If this is itself
            --  implicit, the restriction has already been checked. If not,
            --  it is an explicit loop.

            Rewrite (N,
              Make_Loop_Statement (Sloc (N),
                Identifier => Identifier (N),
                Statements => Statements (N),
                End_Label  => End_Label  (N)));

            Analyze (N);
         end;

      --  Here to deal with iterator case

      elsif Present (Scheme)
        and then Present (Iterator_Specification (Scheme))
      then
         Expand_Iterator_Loop (N);

         --  An iterator loop may generate renaming declarations for elements
         --  that require debug information. This is the case in particular
         --  with element iterators, where debug information must be generated
         --  for the temporary that holds the element value. These temporaries
         --  are created within a transient block whose local declarations are
         --  transferred to the loop, which now has nontrivial local objects.

         if Nkind (N) = N_Loop_Statement
           and then Present (Identifier (N))
         then
            Qualify_Entity_Names (N);
         end if;
      end if;

      --  When the iteration scheme mentions attribute 'Loop_Entry, the loop
      --  is transformed into a conditional block where the original loop is
      --  the sole statement. Inspect the statements of the nested loop for
      --  controlled objects.

      Stmt := N;

      if Subject_To_Loop_Entry_Attributes (Stmt) then
         Stmt := Find_Loop_In_Conditional_Block (Stmt);
      end if;

      Process_Statements_For_Controlled_Objects (Stmt);
   end Expand_N_Loop_Statement;

   ----------------------------
   -- Expand_Predicated_Loop --
   ----------------------------

   --  Note: the expander can handle generation of loops over predicated
   --  subtypes for both the dynamic and static cases. Depending on what
   --  we decide is allowed in Ada 2012 mode and/or extensions allowed
   --  mode, the semantic analyzer may disallow one or both forms.

   procedure Expand_Predicated_Loop (N : Node_Id) is
      Orig_Loop_Id :          Node_Id    := Empty;
      Loc          : constant Source_Ptr := Sloc (N);
      Isc          : constant Node_Id    := Iteration_Scheme (N);
      LPS          : constant Node_Id    := Loop_Parameter_Specification (Isc);
      Loop_Id      : constant Entity_Id  := Defining_Identifier (LPS);
      Ltype        : constant Entity_Id  := Etype (Loop_Id);
      Stat         : constant List_Id    := Static_Discrete_Predicate (Ltype);
      Stmts        : constant List_Id    := Statements (N);

   begin
      --  Case of iteration over non-static predicate, should not be possible
      --  since this is not allowed by the semantics and should have been
      --  caught during analysis of the loop statement.

      if No (Stat) then
         raise Program_Error;

      --  If the predicate list is empty, that corresponds to a predicate of
      --  False, in which case the loop won't run at all, and we rewrite the
      --  entire loop as a null statement.

      elsif Is_Empty_List (Stat) then
         Rewrite (N, Make_Null_Statement (Loc));
         Analyze (N);

      --  For expansion over a static predicate we generate the following

      --     declare
      --        J : Ltype := min-val;
      --     begin
      --        loop
      --           body
      --           case J is
      --              when endpoint => J := startpoint;
      --              when endpoint => J := startpoint;
      --              ...
      --              when max-val  => exit;
      --              when others   => J := Lval'Succ (J);
      --           end case;
      --        end loop;
      --     end;

      --  with min-val replaced by max-val and Succ replaced by Pred if the
      --  loop parameter specification carries a Reverse indicator.

      --  To make this a little clearer, let's take a specific example:

      --        type Int is range 1 .. 10;
      --        subtype StaticP is Int with
      --          predicate => StaticP in 3 | 10 | 5 .. 7;
      --          ...
      --        for L in StaticP loop
      --           Put_Line ("static:" & J'Img);
      --        end loop;

      --  In this case, the loop is transformed into

      --     begin
      --        J : L := 3;
      --        loop
      --           body
      --           case J is
      --              when 3  => J := 5;
      --              when 7  => J := 10;
      --              when 10 => exit;
      --              when others  => J := L'Succ (J);
      --           end case;
      --        end loop;
      --     end;

      --  In addition, if the loop specification is given by a subtype
      --  indication that constrains a predicated type, the bounds of
      --  iteration are given by those of the subtype indication.

      else
         Static_Predicate : declare
            S    : Node_Id;
            D    : Node_Id;
            P    : Node_Id;
            Alts : List_Id;
            Cstm : Node_Id;

            --  If the domain is an itype, note the bounds of its range.

            L_Hi  : Node_Id := Empty;
            L_Lo  : Node_Id := Empty;

            function Lo_Val (N : Node_Id) return Node_Id;
            --  Given static expression or static range, returns an identifier
            --  whose value is the low bound of the expression value or range.

            function Hi_Val (N : Node_Id) return Node_Id;
            --  Given static expression or static range, returns an identifier
            --  whose value is the high bound of the expression value or range.

            ------------
            -- Hi_Val --
            ------------

            function Hi_Val (N : Node_Id) return Node_Id is
            begin
               if Is_OK_Static_Expression (N) then
                  return New_Copy (N);
               else
                  pragma Assert (Nkind (N) = N_Range);
                  return New_Copy (High_Bound (N));
               end if;
            end Hi_Val;

            ------------
            -- Lo_Val --
            ------------

            function Lo_Val (N : Node_Id) return Node_Id is
            begin
               if Is_OK_Static_Expression (N) then
                  return New_Copy (N);
               else
                  pragma Assert (Nkind (N) = N_Range);
                  return New_Copy (Low_Bound (N));
               end if;
            end Lo_Val;

         --  Start of processing for Static_Predicate

         begin
            --  Convert loop identifier to normal variable and reanalyze it so
            --  that this conversion works. We have to use the same defining
            --  identifier, since there may be references in the loop body.

            Set_Analyzed (Loop_Id, False);
            Mutate_Ekind (Loop_Id, E_Variable);

            --  In most loops the loop variable is assigned in various
            --  alternatives in the body. However, in the rare case when
            --  the range specifies a single element, the loop variable
            --  may trigger a spurious warning that is could be constant.
            --  This warning might as well be suppressed.

            Set_Warnings_Off (Loop_Id);

            if Is_Itype (Ltype) then
               L_Hi := High_Bound (Scalar_Range (Ltype));
               L_Lo := Low_Bound  (Scalar_Range (Ltype));
            end if;

            --  Loop to create branches of case statement

            Alts := New_List;

            if Reverse_Present (LPS) then

               --  Initial value is largest value in predicate.

               if Is_Itype (Ltype) then
                  D :=
                    Make_Object_Declaration (Loc,
                      Defining_Identifier => Loop_Id,
                      Object_Definition   => New_Occurrence_Of (Ltype, Loc),
                      Expression          => L_Hi);

               else
                  D :=
                    Make_Object_Declaration (Loc,
                      Defining_Identifier => Loop_Id,
                      Object_Definition   => New_Occurrence_Of (Ltype, Loc),
                      Expression          => Hi_Val (Last (Stat)));
               end if;

               P := Last (Stat);
               while Present (P) loop
                  if No (Prev (P)) then
                     S := Make_Exit_Statement (Loc);
                  else
                     S :=
                       Make_Assignment_Statement (Loc,
                         Name       => New_Occurrence_Of (Loop_Id, Loc),
                         Expression => Hi_Val (Prev (P)));
                     Set_Suppress_Assignment_Checks (S);
                  end if;

                  Append_To (Alts,
                    Make_Case_Statement_Alternative (Loc,
                      Statements       => New_List (S),
                      Discrete_Choices => New_List (Lo_Val (P))));

                  Prev (P);
               end loop;

               if Is_Itype (Ltype)
                 and then Is_OK_Static_Expression (L_Lo)
                 and then
                   Expr_Value (L_Lo) /= Expr_Value (Lo_Val (First (Stat)))
               then
                  Append_To (Alts,
                    Make_Case_Statement_Alternative (Loc,
                      Statements       => New_List (Make_Exit_Statement (Loc)),
                      Discrete_Choices => New_List (L_Lo)));
               end if;

            else
               --  Initial value is smallest value in predicate

               if Is_Itype (Ltype) then
                  D :=
                    Make_Object_Declaration (Loc,
                      Defining_Identifier => Loop_Id,
                      Object_Definition   => New_Occurrence_Of (Ltype, Loc),
                      Expression          => L_Lo);
               else
                  D :=
                    Make_Object_Declaration (Loc,
                      Defining_Identifier => Loop_Id,
                      Object_Definition   => New_Occurrence_Of (Ltype, Loc),
                      Expression          => Lo_Val (First (Stat)));
               end if;

               P := First (Stat);
               while Present (P) loop
                  if No (Next (P)) then
                     S := Make_Exit_Statement (Loc);
                  else
                     S :=
                       Make_Assignment_Statement (Loc,
                         Name       => New_Occurrence_Of (Loop_Id, Loc),
                         Expression => Lo_Val (Next (P)));
                     Set_Suppress_Assignment_Checks (S);
                  end if;

                  Append_To (Alts,
                    Make_Case_Statement_Alternative (Loc,
                      Statements       => New_List (S),
                      Discrete_Choices => New_List (Hi_Val (P))));

                  Next (P);
               end loop;

               if Is_Itype (Ltype)
                 and then Is_OK_Static_Expression (L_Hi)
                 and then
                   Expr_Value (L_Hi) /= Expr_Value (Lo_Val (Last (Stat)))
               then
                  Append_To (Alts,
                    Make_Case_Statement_Alternative (Loc,
                      Statements       => New_List (Make_Exit_Statement (Loc)),
                      Discrete_Choices => New_List (L_Hi)));
               end if;
            end if;

            --  Add others choice

            declare
               Name_Next : Name_Id;

            begin
               if Reverse_Present (LPS) then
                  Name_Next := Name_Pred;
               else
                  Name_Next := Name_Succ;
               end if;

               S :=
                 Make_Assignment_Statement (Loc,
                   Name       => New_Occurrence_Of (Loop_Id, Loc),
                   Expression =>
                     Make_Attribute_Reference (Loc,
                       Prefix         => New_Occurrence_Of (Ltype, Loc),
                       Attribute_Name => Name_Next,
                       Expressions    => New_List (
                         New_Occurrence_Of (Loop_Id, Loc))));
               Set_Suppress_Assignment_Checks (S);
            end;

            Append_To (Alts,
              Make_Case_Statement_Alternative (Loc,
                Discrete_Choices => New_List (Make_Others_Choice (Loc)),
                Statements       => New_List (S)));

            --  Construct case statement and append to body statements

            Cstm :=
              Make_Case_Statement (Loc,
                Expression   => New_Occurrence_Of (Loop_Id, Loc),
                Alternatives => Alts);
            Append_To (Stmts, Cstm);

            --  Rewrite the loop preserving the loop identifier in case there
            --  are exit statements referencing it.

            if Present (Identifier (N)) then
               Orig_Loop_Id := New_Occurrence_Of
                                 (Entity (Identifier (N)), Loc);
            end if;

            Set_Suppress_Assignment_Checks (D);

            Rewrite (N,
              Make_Block_Statement (Loc,
                Declarations               => New_List (D),
                Handled_Statement_Sequence =>
                  Make_Handled_Sequence_Of_Statements (Loc,
                    Statements => New_List (
                      Make_Loop_Statement (Loc,
                        Statements => Stmts,
                        Identifier => Orig_Loop_Id,
                        End_Label  => Empty)))));

            Analyze (N);
         end Static_Predicate;
      end if;
   end Expand_Predicated_Loop;

   ------------------------------
   -- Make_Tag_Ctrl_Assignment --
   ------------------------------

   function Make_Tag_Ctrl_Assignment (N : Node_Id) return List_Id is
      Asn : constant Node_Id    := Relocate_Node (N);
      L   : constant Node_Id    := Name (N);
      Loc : constant Source_Ptr := Sloc (N);
      Res : constant List_Id    := New_List;
      T   : constant Entity_Id  := Underlying_Type (Etype (L));

      Comp_Asn : constant Boolean := Is_Fully_Repped_Tagged_Type (T);
      Ctrl_Act : constant Boolean := Needs_Finalization (T)
                                       and then not No_Ctrl_Actions (N);
      Save_Tag : constant Boolean := Is_Tagged_Type (T)
                                       and then not Comp_Asn
                                       and then not No_Ctrl_Actions (N)
                                       and then Tagged_Type_Expansion;
      Adj_Call : Node_Id;
      Fin_Call : Node_Id;
      Tag_Id   : Entity_Id;

   begin
      --  Finalize the target of the assignment when controlled

      --  We have two exceptions here:

      --   1. If we are in an init proc since it is an initialization more
      --      than an assignment.

      --   2. If the left-hand side is a temporary that was not initialized
      --      (or the parent part of a temporary since it is the case in
      --      extension aggregates). Such a temporary does not come from
      --      source. We must examine the original node for the prefix, because
      --      it may be a component of an entry formal, in which case it has
      --      been rewritten and does not appear to come from source either.

      --  Case of init proc

      if not Ctrl_Act then
         null;

      --  The left-hand side is an uninitialized temporary object

      elsif Nkind (L) = N_Type_Conversion
        and then Is_Entity_Name (Expression (L))
        and then Nkind (Parent (Entity (Expression (L)))) =
                                              N_Object_Declaration
        and then No_Initialization (Parent (Entity (Expression (L))))
      then
         null;

      else
         Fin_Call :=
           Make_Final_Call
             (Obj_Ref => Duplicate_Subexpr_No_Checks (L),
              Typ     => Etype (L));

         if Present (Fin_Call) then
            Append_To (Res, Fin_Call);
         end if;
      end if;

      --  Save the Tag in a local variable Tag_Id

      if Save_Tag then
         Tag_Id := Make_Temporary (Loc, 'A');

         Append_To (Res,
           Make_Object_Declaration (Loc,
             Defining_Identifier => Tag_Id,
             Object_Definition   => New_Occurrence_Of (RTE (RE_Tag), Loc),
             Expression          =>
               Make_Selected_Component (Loc,
                 Prefix        => Duplicate_Subexpr_No_Checks (L),
                 Selector_Name =>
                   New_Occurrence_Of (First_Tag_Component (T), Loc))));

      --  Otherwise Tag_Id is not used

      else
         Tag_Id := Empty;
      end if;

      --  If the tagged type has a full rep clause, expand the assignment into
      --  component-wise assignments. Mark the node as unanalyzed in order to
      --  generate the proper code and propagate this scenario by setting a
      --  flag to avoid infinite recursion.

      if Comp_Asn then
         Set_Analyzed (Asn, False);
         Set_Componentwise_Assignment (Asn, True);
      end if;

      Append_To (Res, Asn);

      --  Restore the tag

      if Save_Tag then
         Append_To (Res,
           Make_Assignment_Statement (Loc,
             Name       =>
               Make_Selected_Component (Loc,
                 Prefix        => Duplicate_Subexpr_No_Checks (L),
                 Selector_Name =>
                   New_Occurrence_Of (First_Tag_Component (T), Loc)),
             Expression => New_Occurrence_Of (Tag_Id, Loc)));
      end if;

      --  Adjust the target after the assignment when controlled (not in the
      --  init proc since it is an initialization more than an assignment).

      if Ctrl_Act then
         Adj_Call :=
           Make_Adjust_Call
             (Obj_Ref => Duplicate_Subexpr_Move_Checks (L),
              Typ     => Etype (L));

         if Present (Adj_Call) then
            Append_To (Res, Adj_Call);
         end if;
      end if;

      return Res;

   exception

      --  Could use comment here ???

      when RE_Not_Available =>
         return Empty_List;
   end Make_Tag_Ctrl_Assignment;

end Exp_Ch5;
