------------------------------------------------------------------------------
--                                                                          --
--                         GNAT COMPILER COMPONENTS                         --
--                                                                          --
--                              E X P _ C H 4                               --
--                                                                          --
--                                 B o d y                                  --
--                                                                          --
--          Copyright (C) 1992-2019, 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 Atree;    use Atree;
with Checks;   use Checks;
with Debug;    use Debug;
with Einfo;    use Einfo;
with Elists;   use Elists;
with Errout;   use Errout;
with Exp_Aggr; use Exp_Aggr;
with Exp_Atag; use Exp_Atag;
with Exp_Ch2;  use Exp_Ch2;
with Exp_Ch3;  use Exp_Ch3;
with Exp_Ch6;  use Exp_Ch6;
with Exp_Ch7;  use Exp_Ch7;
with Exp_Ch9;  use Exp_Ch9;
with Exp_Disp; use Exp_Disp;
with Exp_Fixd; use Exp_Fixd;
with Exp_Intr; use Exp_Intr;
with Exp_Pakd; use Exp_Pakd;
with Exp_Tss;  use Exp_Tss;
with Exp_Util; use Exp_Util;
with Freeze;   use Freeze;
with Inline;   use Inline;
with Namet;    use Namet;
with Nlists;   use Nlists;
with Nmake;    use Nmake;
with Opt;      use Opt;
with Par_SCO;  use Par_SCO;
with Restrict; use Restrict;
with Rident;   use Rident;
with Rtsfind;  use Rtsfind;
with Sem;      use Sem;
with Sem_Aux;  use Sem_Aux;
with Sem_Cat;  use Sem_Cat;
with Sem_Ch3;  use Sem_Ch3;
with Sem_Ch13; use Sem_Ch13;
with Sem_Eval; use Sem_Eval;
with Sem_Res;  use Sem_Res;
with Sem_Type; use Sem_Type;
with Sem_Util; use Sem_Util;
with Sem_Warn; use Sem_Warn;
with Sinfo;    use Sinfo;
with Snames;   use Snames;
with Stand;    use Stand;
with SCIL_LL;  use SCIL_LL;
with Targparm; use Targparm;
with Tbuild;   use Tbuild;
with Ttypes;   use Ttypes;
with Uintp;    use Uintp;
with Urealp;   use Urealp;
with Validsw;  use Validsw;
with Warnsw;   use Warnsw;

package body Exp_Ch4 is

   -----------------------
   -- Local Subprograms --
   -----------------------

   procedure Binary_Op_Validity_Checks (N : Node_Id);
   pragma Inline (Binary_Op_Validity_Checks);
   --  Performs validity checks for a binary operator

   procedure Build_Boolean_Array_Proc_Call
     (N   : Node_Id;
      Op1 : Node_Id;
      Op2 : Node_Id);
   --  If a boolean array assignment can be done in place, build call to
   --  corresponding library procedure.

   procedure Displace_Allocator_Pointer (N : Node_Id);
   --  Ada 2005 (AI-251): Subsidiary procedure to Expand_N_Allocator and
   --  Expand_Allocator_Expression. Allocating class-wide interface objects
   --  this routine displaces the pointer to the allocated object to reference
   --  the component referencing the corresponding secondary dispatch table.

   procedure Expand_Allocator_Expression (N : Node_Id);
   --  Subsidiary to Expand_N_Allocator, for the case when the expression
   --  is a qualified expression or an aggregate.

   procedure Expand_Array_Comparison (N : Node_Id);
   --  This routine handles expansion of the comparison operators (N_Op_Lt,
   --  N_Op_Le, N_Op_Gt, N_Op_Ge) when operating on an array type. The basic
   --  code for these operators is similar, differing only in the details of
   --  the actual comparison call that is made. Special processing (call a
   --  run-time routine)

   function Expand_Array_Equality
     (Nod    : Node_Id;
      Lhs    : Node_Id;
      Rhs    : Node_Id;
      Bodies : List_Id;
      Typ    : Entity_Id) return Node_Id;
   --  Expand an array equality into a call to a function implementing this
   --  equality, and a call to it. Loc is the location for the generated nodes.
   --  Lhs and Rhs are the array expressions to be compared. Bodies is a list
   --  on which to attach bodies of local functions that are created in the
   --  process. It is the responsibility of the caller to insert those bodies
   --  at the right place. Nod provides the Sloc value for the generated code.
   --  Normally the types used for the generated equality routine are taken
   --  from Lhs and Rhs. However, in some situations of generated code, the
   --  Etype fields of Lhs and Rhs are not set yet. In such cases, Typ supplies
   --  the type to be used for the formal parameters.

   procedure Expand_Boolean_Operator (N : Node_Id);
   --  Common expansion processing for Boolean operators (And, Or, Xor) for the
   --  case of array type arguments.

   procedure Expand_Nonbinary_Modular_Op (N : Node_Id);
   --  When generating C code, convert nonbinary modular arithmetic operations
   --  into code that relies on the front-end expansion of operator Mod. No
   --  expansion is performed if N is not a nonbinary modular operand.

   procedure Expand_Short_Circuit_Operator (N : Node_Id);
   --  Common expansion processing for short-circuit boolean operators

   procedure Expand_Compare_Minimize_Eliminate_Overflow (N : Node_Id);
   --  Deal with comparison in MINIMIZED/ELIMINATED overflow mode. This is
   --  where we allow comparison of "out of range" values.

   function Expand_Composite_Equality
     (Nod    : Node_Id;
      Typ    : Entity_Id;
      Lhs    : Node_Id;
      Rhs    : Node_Id;
      Bodies : List_Id) return Node_Id;
   --  Local recursive function used to expand equality for nested composite
   --  types. Used by Expand_Record/Array_Equality, Bodies is a list on which
   --  to attach bodies of local functions that are created in the process. It
   --  is the responsibility of the caller to insert those bodies at the right
   --  place. Nod provides the Sloc value for generated code. Lhs and Rhs are
   --  the left and right sides for the comparison, and Typ is the type of the
   --  objects to compare.

   procedure Expand_Concatenate (Cnode : Node_Id; Opnds : List_Id);
   --  Routine to expand concatenation of a sequence of two or more operands
   --  (in the list Operands) and replace node Cnode with the result of the
   --  concatenation. The operands can be of any appropriate type, and can
   --  include both arrays and singleton elements.

   procedure Expand_Membership_Minimize_Eliminate_Overflow (N : Node_Id);
   --  N is an N_In membership test mode, with the overflow check mode set to
   --  MINIMIZED or ELIMINATED, and the type of the left operand is a signed
   --  integer type. This is a case where top level processing is required to
   --  handle overflow checks in subtrees.

   procedure Fixup_Universal_Fixed_Operation (N : Node_Id);
   --  N is a N_Op_Divide or N_Op_Multiply node whose result is universal
   --  fixed. We do not have such a type at runtime, so the purpose of this
   --  routine is to find the real type by looking up the tree. We also
   --  determine if the operation must be rounded.

   function Has_Inferable_Discriminants (N : Node_Id) return Boolean;
   --  Ada 2005 (AI-216): A view of an Unchecked_Union object has inferable
   --  discriminants if it has a constrained nominal type, unless the object
   --  is a component of an enclosing Unchecked_Union object that is subject
   --  to a per-object constraint and the enclosing object lacks inferable
   --  discriminants.
   --
   --  An expression of an Unchecked_Union type has inferable discriminants
   --  if it is either a name of an object with inferable discriminants or a
   --  qualified expression whose subtype mark denotes a constrained subtype.

   procedure Insert_Dereference_Action (N : Node_Id);
   --  N is an expression whose type is an access. When the type of the
   --  associated storage pool is derived from Checked_Pool, generate a
   --  call to the 'Dereference' primitive operation.

   function Make_Array_Comparison_Op
     (Typ : Entity_Id;
      Nod : Node_Id) return Node_Id;
   --  Comparisons between arrays are expanded in line. This function produces
   --  the body of the implementation of (a > b), where a and b are one-
   --  dimensional arrays of some discrete type. The original node is then
   --  expanded into the appropriate call to this function. Nod provides the
   --  Sloc value for the generated code.

   function Make_Boolean_Array_Op
     (Typ : Entity_Id;
      N   : Node_Id) return Node_Id;
   --  Boolean operations on boolean arrays are expanded in line. This function
   --  produce the body for the node N, which is (a and b), (a or b), or (a xor
   --  b). It is used only the normal case and not the packed case. The type
   --  involved, Typ, is the Boolean array type, and the logical operations in
   --  the body are simple boolean operations. Note that Typ is always a
   --  constrained type (the caller has ensured this by using
   --  Convert_To_Actual_Subtype if necessary).

   function Minimized_Eliminated_Overflow_Check (N : Node_Id) return Boolean;
   --  For signed arithmetic operations when the current overflow mode is
   --  MINIMIZED or ELIMINATED, we must call Apply_Arithmetic_Overflow_Checks
   --  as the first thing we do. We then return. We count on the recursive
   --  apparatus for overflow checks to call us back with an equivalent
   --  operation that is in CHECKED mode, avoiding a recursive entry into this
   --  routine, and that is when we will proceed with the expansion of the
   --  operator (e.g. converting X+0 to X, or X**2 to X*X). We cannot do
   --  these optimizations without first making this check, since there may be
   --  operands further down the tree that are relying on the recursive calls
   --  triggered by the top level nodes to properly process overflow checking
   --  and remaining expansion on these nodes. Note that this call back may be
   --  skipped if the operation is done in Bignum mode but that's fine, since
   --  the Bignum call takes care of everything.

   procedure Optimize_Length_Comparison (N : Node_Id);
   --  Given an expression, if it is of the form X'Length op N (or the other
   --  way round), where N is known at compile time to be 0 or 1, and X is a
   --  simple entity, and op is a comparison operator, optimizes it into a
   --  comparison of First and Last.

   procedure Process_If_Case_Statements (N : Node_Id; Stmts : List_Id);
   --  Inspect and process statement list Stmt of if or case expression N for
   --  transient objects. If such objects are found, the routine generates code
   --  to clean them up when the context of the expression is evaluated.

   procedure Process_Transient_In_Expression
     (Obj_Decl : Node_Id;
      Expr     : Node_Id;
      Stmts    : List_Id);
   --  Subsidiary routine to the expansion of expression_with_actions, if and
   --  case expressions. Generate all necessary code to finalize a transient
   --  object when the enclosing context is elaborated or evaluated. Obj_Decl
   --  denotes the declaration of the transient object, which is usually the
   --  result of a controlled function call. Expr denotes the expression with
   --  actions, if expression, or case expression node. Stmts denotes the
   --  statement list which contains Decl, either at the top level or within a
   --  nested construct.

   procedure Rewrite_Comparison (N : Node_Id);
   --  If N is the node for a comparison whose outcome can be determined at
   --  compile time, then the node N can be rewritten with True or False. If
   --  the outcome cannot be determined at compile time, the call has no
   --  effect. If N is a type conversion, then this processing is applied to
   --  its expression. If N is neither comparison nor a type conversion, the
   --  call has no effect.

   procedure Tagged_Membership
     (N         : Node_Id;
      SCIL_Node : out Node_Id;
      Result    : out Node_Id);
   --  Construct the expression corresponding to the tagged membership test.
   --  Deals with a second operand being (or not) a class-wide type.

   function Safe_In_Place_Array_Op
     (Lhs : Node_Id;
      Op1 : Node_Id;
      Op2 : Node_Id) return Boolean;
   --  In the context of an assignment, where the right-hand side is a boolean
   --  operation on arrays, check whether operation can be performed in place.

   procedure Unary_Op_Validity_Checks (N : Node_Id);
   pragma Inline (Unary_Op_Validity_Checks);
   --  Performs validity checks for a unary operator

   -------------------------------
   -- Binary_Op_Validity_Checks --
   -------------------------------

   procedure Binary_Op_Validity_Checks (N : Node_Id) is
   begin
      if Validity_Checks_On and Validity_Check_Operands then
         Ensure_Valid (Left_Opnd (N));
         Ensure_Valid (Right_Opnd (N));
      end if;
   end Binary_Op_Validity_Checks;

   ------------------------------------
   -- Build_Boolean_Array_Proc_Call --
   ------------------------------------

   procedure Build_Boolean_Array_Proc_Call
     (N   : Node_Id;
      Op1 : Node_Id;
      Op2 : Node_Id)
   is
      Loc       : constant Source_Ptr := Sloc (N);
      Kind      : constant Node_Kind := Nkind (Expression (N));
      Target    : constant Node_Id   :=
                    Make_Attribute_Reference (Loc,
                      Prefix         => Name (N),
                      Attribute_Name => Name_Address);

      Arg1      : Node_Id := Op1;
      Arg2      : Node_Id := Op2;
      Call_Node : Node_Id;
      Proc_Name : Entity_Id;

   begin
      if Kind = N_Op_Not then
         if Nkind (Op1) in N_Binary_Op then

            --  Use negated version of the binary operators

            if Nkind (Op1) = N_Op_And then
               Proc_Name := RTE (RE_Vector_Nand);

            elsif Nkind (Op1) = N_Op_Or then
               Proc_Name := RTE (RE_Vector_Nor);

            else pragma Assert (Nkind (Op1) = N_Op_Xor);
               Proc_Name := RTE (RE_Vector_Xor);
            end if;

            Call_Node :=
              Make_Procedure_Call_Statement (Loc,
                Name => New_Occurrence_Of (Proc_Name, Loc),

                Parameter_Associations => New_List (
                  Target,
                  Make_Attribute_Reference (Loc,
                    Prefix => Left_Opnd (Op1),
                    Attribute_Name => Name_Address),

                  Make_Attribute_Reference (Loc,
                    Prefix => Right_Opnd (Op1),
                    Attribute_Name => Name_Address),

                  Make_Attribute_Reference (Loc,
                    Prefix => Left_Opnd (Op1),
                    Attribute_Name => Name_Length)));

         else
            Proc_Name := RTE (RE_Vector_Not);

            Call_Node :=
              Make_Procedure_Call_Statement (Loc,
                Name => New_Occurrence_Of (Proc_Name, Loc),
                Parameter_Associations => New_List (
                  Target,

                  Make_Attribute_Reference (Loc,
                    Prefix => Op1,
                    Attribute_Name => Name_Address),

                  Make_Attribute_Reference (Loc,
                    Prefix => Op1,
                     Attribute_Name => Name_Length)));
         end if;

      else
         --  We use the following equivalences:

         --   (not X) or  (not Y)  =  not (X and Y)  =  Nand (X, Y)
         --   (not X) and (not Y)  =  not (X or Y)   =  Nor  (X, Y)
         --   (not X) xor (not Y)  =  X xor Y
         --   X       xor (not Y)  =  not (X xor Y)  =  Nxor (X, Y)

         if Nkind (Op1) = N_Op_Not then
            Arg1 := Right_Opnd (Op1);
            Arg2 := Right_Opnd (Op2);

            if Kind = N_Op_And then
               Proc_Name := RTE (RE_Vector_Nor);
            elsif Kind = N_Op_Or then
               Proc_Name := RTE (RE_Vector_Nand);
            else
               Proc_Name := RTE (RE_Vector_Xor);
            end if;

         else
            if Kind = N_Op_And then
               Proc_Name := RTE (RE_Vector_And);
            elsif Kind = N_Op_Or then
               Proc_Name := RTE (RE_Vector_Or);
            elsif Nkind (Op2) = N_Op_Not then
               Proc_Name := RTE (RE_Vector_Nxor);
               Arg2 := Right_Opnd (Op2);
            else
               Proc_Name := RTE (RE_Vector_Xor);
            end if;
         end if;

         Call_Node :=
           Make_Procedure_Call_Statement (Loc,
             Name => New_Occurrence_Of (Proc_Name, Loc),
             Parameter_Associations => New_List (
               Target,
               Make_Attribute_Reference (Loc,
                 Prefix         => Arg1,
                 Attribute_Name => Name_Address),
               Make_Attribute_Reference (Loc,
                 Prefix         => Arg2,
                 Attribute_Name => Name_Address),
               Make_Attribute_Reference (Loc,
                 Prefix         => Arg1,
                 Attribute_Name => Name_Length)));
      end if;

      Rewrite (N, Call_Node);
      Analyze (N);

   exception
      when RE_Not_Available =>
         return;
   end Build_Boolean_Array_Proc_Call;

   -----------------------
   -- Build_Eq_Call --
   -----------------------

   function Build_Eq_Call
     (Typ : Entity_Id;
      Loc : Source_Ptr;
      Lhs : Node_Id;
      Rhs : Node_Id) return Node_Id
   is
      Prim   : Node_Id;
      Prim_E : Elmt_Id;

   begin
      Prim_E := First_Elmt (Collect_Primitive_Operations (Typ));
      while Present (Prim_E) loop
         Prim := Node (Prim_E);

         --  Locate primitive equality with the right signature

         if Chars (Prim) = Name_Op_Eq
           and then Etype (First_Formal (Prim)) =
                    Etype (Next_Formal (First_Formal (Prim)))
           and then Etype (Prim) = Standard_Boolean
         then
            if Is_Abstract_Subprogram (Prim) then
               return
                 Make_Raise_Program_Error (Loc,
                   Reason => PE_Explicit_Raise);

            else
               return
                 Make_Function_Call (Loc,
                   Name                   => New_Occurrence_Of (Prim, Loc),
                   Parameter_Associations => New_List (Lhs, Rhs));
            end if;
         end if;

         Next_Elmt (Prim_E);
      end loop;

      --  If not found, predefined operation will be used

      return Empty;
   end Build_Eq_Call;

   --------------------------------
   -- Displace_Allocator_Pointer --
   --------------------------------

   procedure Displace_Allocator_Pointer (N : Node_Id) is
      Loc       : constant Source_Ptr := Sloc (N);
      Orig_Node : constant Node_Id := Original_Node (N);
      Dtyp      : Entity_Id;
      Etyp      : Entity_Id;
      PtrT      : Entity_Id;

   begin
      --  Do nothing in case of VM targets: the virtual machine will handle
      --  interfaces directly.

      if not Tagged_Type_Expansion then
         return;
      end if;

      pragma Assert (Nkind (N) = N_Identifier
        and then Nkind (Orig_Node) = N_Allocator);

      PtrT := Etype (Orig_Node);
      Dtyp := Available_View (Designated_Type (PtrT));
      Etyp := Etype (Expression (Orig_Node));

      if Is_Class_Wide_Type (Dtyp) and then Is_Interface (Dtyp) then

         --  If the type of the allocator expression is not an interface type
         --  we can generate code to reference the record component containing
         --  the pointer to the secondary dispatch table.

         if not Is_Interface (Etyp) then
            declare
               Saved_Typ : constant Entity_Id := Etype (Orig_Node);

            begin
               --  1) Get access to the allocated object

               Rewrite (N,
                 Make_Explicit_Dereference (Loc, Relocate_Node (N)));
               Set_Etype (N, Etyp);
               Set_Analyzed (N);

               --  2) Add the conversion to displace the pointer to reference
               --     the secondary dispatch table.

               Rewrite (N, Convert_To (Dtyp, Relocate_Node (N)));
               Analyze_And_Resolve (N, Dtyp);

               --  3) The 'access to the secondary dispatch table will be used
               --     as the value returned by the allocator.

               Rewrite (N,
                 Make_Attribute_Reference (Loc,
                   Prefix         => Relocate_Node (N),
                   Attribute_Name => Name_Access));
               Set_Etype (N, Saved_Typ);
               Set_Analyzed (N);
            end;

         --  If the type of the allocator expression is an interface type we
         --  generate a run-time call to displace "this" to reference the
         --  component containing the pointer to the secondary dispatch table
         --  or else raise Constraint_Error if the actual object does not
         --  implement the target interface. This case corresponds to the
         --  following example:

         --   function Op (Obj : Iface_1'Class) return access Iface_2'Class is
         --   begin
         --      return new Iface_2'Class'(Obj);
         --   end Op;

         else
            Rewrite (N,
              Unchecked_Convert_To (PtrT,
                Make_Function_Call (Loc,
                  Name => New_Occurrence_Of (RTE (RE_Displace), Loc),
                  Parameter_Associations => New_List (
                    Unchecked_Convert_To (RTE (RE_Address),
                      Relocate_Node (N)),

                    New_Occurrence_Of
                      (Elists.Node
                        (First_Elmt
                          (Access_Disp_Table (Etype (Base_Type (Dtyp))))),
                       Loc)))));
            Analyze_And_Resolve (N, PtrT);
         end if;
      end if;
   end Displace_Allocator_Pointer;

   ---------------------------------
   -- Expand_Allocator_Expression --
   ---------------------------------

   procedure Expand_Allocator_Expression (N : Node_Id) is
      Loc    : constant Source_Ptr := Sloc (N);
      Exp    : constant Node_Id    := Expression (Expression (N));
      PtrT   : constant Entity_Id  := Etype (N);
      DesigT : constant Entity_Id  := Designated_Type (PtrT);

      procedure Apply_Accessibility_Check
        (Ref            : Node_Id;
         Built_In_Place : Boolean := False);
      --  Ada 2005 (AI-344): For an allocator with a class-wide designated
      --  type, generate an accessibility check to verify that the level of the
      --  type of the created object is not deeper than the level of the access
      --  type. If the type of the qualified expression is class-wide, then
      --  always generate the check (except in the case where it is known to be
      --  unnecessary, see comment below). Otherwise, only generate the check
      --  if the level of the qualified expression type is statically deeper
      --  than the access type.
      --
      --  Although the static accessibility will generally have been performed
      --  as a legality check, it won't have been done in cases where the
      --  allocator appears in generic body, so a run-time check is needed in
      --  general. One special case is when the access type is declared in the
      --  same scope as the class-wide allocator, in which case the check can
      --  never fail, so it need not be generated.
      --
      --  As an open issue, there seem to be cases where the static level
      --  associated with the class-wide object's underlying type is not
      --  sufficient to perform the proper accessibility check, such as for
      --  allocators in nested subprograms or accept statements initialized by
      --  class-wide formals when the actual originates outside at a deeper
      --  static level. The nested subprogram case might require passing
      --  accessibility levels along with class-wide parameters, and the task
      --  case seems to be an actual gap in the language rules that needs to
      --  be fixed by the ARG. ???

      -------------------------------
      -- Apply_Accessibility_Check --
      -------------------------------

      procedure Apply_Accessibility_Check
        (Ref            : Node_Id;
         Built_In_Place : Boolean := False)
      is
         Pool_Id   : constant Entity_Id := Associated_Storage_Pool (PtrT);
         Cond      : Node_Id;
         Fin_Call  : Node_Id;
         Free_Stmt : Node_Id;
         Obj_Ref   : Node_Id;
         Stmts     : List_Id;

      begin
         if Ada_Version >= Ada_2005
           and then Is_Class_Wide_Type (DesigT)
           and then Tagged_Type_Expansion
           and then not Scope_Suppress.Suppress (Accessibility_Check)
           and then
             (Type_Access_Level (Etype (Exp)) > Type_Access_Level (PtrT)
               or else
                 (Is_Class_Wide_Type (Etype (Exp))
                   and then Scope (PtrT) /= Current_Scope))
         then
            --  If the allocator was built in place, Ref is already a reference
            --  to the access object initialized to the result of the allocator
            --  (see Exp_Ch6.Make_Build_In_Place_Call_In_Allocator). We call
            --  Remove_Side_Effects for cases where the build-in-place call may
            --  still be the prefix of the reference (to avoid generating
            --  duplicate calls). Otherwise, it is the entity associated with
            --  the object containing the address of the allocated object.

            if Built_In_Place then
               Remove_Side_Effects (Ref);
               Obj_Ref := New_Copy_Tree (Ref);
            else
               Obj_Ref := New_Occurrence_Of (Ref, Loc);
            end if;

            --  For access to interface types we must generate code to displace
            --  the pointer to the base of the object since the subsequent code
            --  references components located in the TSD of the object (which
            --  is associated with the primary dispatch table --see a-tags.ads)
            --  and also generates code invoking Free, which requires also a
            --  reference to the base of the unallocated object.

            if Is_Interface (DesigT) and then Tagged_Type_Expansion then
               Obj_Ref :=
                 Unchecked_Convert_To (Etype (Obj_Ref),
                   Make_Function_Call (Loc,
                     Name                   =>
                       New_Occurrence_Of (RTE (RE_Base_Address), Loc),
                     Parameter_Associations => New_List (
                       Unchecked_Convert_To (RTE (RE_Address),
                         New_Copy_Tree (Obj_Ref)))));
            end if;

            --  Step 1: Create the object clean up code

            Stmts := New_List;

            --  Deallocate the object if the accessibility check fails. This
            --  is done only on targets or profiles that support deallocation.

            --    Free (Obj_Ref);

            if RTE_Available (RE_Free) then
               Free_Stmt := Make_Free_Statement (Loc, New_Copy_Tree (Obj_Ref));
               Set_Storage_Pool (Free_Stmt, Pool_Id);

               Append_To (Stmts, Free_Stmt);

            --  The target or profile cannot deallocate objects

            else
               Free_Stmt := Empty;
            end if;

            --  Finalize the object if applicable. Generate:

            --    [Deep_]Finalize (Obj_Ref.all);

            if Needs_Finalization (DesigT)
              and then not No_Heap_Finalization (PtrT)
            then
               Fin_Call :=
                 Make_Final_Call
                   (Obj_Ref =>
                      Make_Explicit_Dereference (Loc, New_Copy (Obj_Ref)),
                    Typ     => DesigT);

               --  Guard against a missing [Deep_]Finalize when the designated
               --  type was not properly frozen.

               if No (Fin_Call) then
                  Fin_Call := Make_Null_Statement (Loc);
               end if;

               --  When the target or profile supports deallocation, wrap the
               --  finalization call in a block to ensure proper deallocation
               --  even if finalization fails. Generate:

               --    begin
               --       <Fin_Call>
               --    exception
               --       when others =>
               --          <Free_Stmt>
               --          raise;
               --    end;

               if Present (Free_Stmt) then
                  Fin_Call :=
                    Make_Block_Statement (Loc,
                      Handled_Statement_Sequence =>
                        Make_Handled_Sequence_Of_Statements (Loc,
                          Statements => New_List (Fin_Call),

                        Exception_Handlers => New_List (
                          Make_Exception_Handler (Loc,
                            Exception_Choices => New_List (
                              Make_Others_Choice (Loc)),
                            Statements        => New_List (
                              New_Copy_Tree (Free_Stmt),
                              Make_Raise_Statement (Loc))))));
               end if;

               Prepend_To (Stmts, Fin_Call);
            end if;

            --  Signal the accessibility failure through a Program_Error

            Append_To (Stmts,
              Make_Raise_Program_Error (Loc,
                Condition => New_Occurrence_Of (Standard_True, Loc),
                Reason    => PE_Accessibility_Check_Failed));

            --  Step 2: Create the accessibility comparison

            --  Generate:
            --    Ref'Tag

            Obj_Ref :=
              Make_Attribute_Reference (Loc,
                Prefix         => Obj_Ref,
                Attribute_Name => Name_Tag);

            --  For tagged types, determine the accessibility level by looking
            --  at the type specific data of the dispatch table. Generate:

            --    Type_Specific_Data (Address (Ref'Tag)).Access_Level

            if Tagged_Type_Expansion then
               Cond := Build_Get_Access_Level (Loc, Obj_Ref);

            --  Use a runtime call to determine the accessibility level when
            --  compiling on virtual machine targets. Generate:

            --    Get_Access_Level (Ref'Tag)

            else
               Cond :=
                 Make_Function_Call (Loc,
                   Name                   =>
                     New_Occurrence_Of (RTE (RE_Get_Access_Level), Loc),
                   Parameter_Associations => New_List (Obj_Ref));
            end if;

            Cond :=
              Make_Op_Gt (Loc,
                Left_Opnd  => Cond,
                Right_Opnd =>
                  Make_Integer_Literal (Loc, Type_Access_Level (PtrT)));

            --  Due to the complexity and side effects of the check, utilize an
            --  if statement instead of the regular Program_Error circuitry.

            Insert_Action (N,
              Make_Implicit_If_Statement (N,
                Condition       => Cond,
                Then_Statements => Stmts));
         end if;
      end Apply_Accessibility_Check;

      --  Local variables

      Aggr_In_Place : constant Boolean   := Is_Delayed_Aggregate (Exp);
      Indic         : constant Node_Id   := Subtype_Mark (Expression (N));
      T             : constant Entity_Id := Entity (Indic);
      Adj_Call      : Node_Id;
      Node          : Node_Id;
      Tag_Assign    : Node_Id;
      Temp          : Entity_Id;
      Temp_Decl     : Node_Id;

      TagT : Entity_Id := Empty;
      --  Type used as source for tag assignment

      TagR : Node_Id := Empty;
      --  Target reference for tag assignment

   --  Start of processing for Expand_Allocator_Expression

   begin
      --  Handle call to C++ constructor

      if Is_CPP_Constructor_Call (Exp) then
         Make_CPP_Constructor_Call_In_Allocator
           (Allocator => N,
            Function_Call => Exp);
         return;
      end if;

      --  In the case of an Ada 2012 allocator whose initial value comes from a
      --  function call, pass "the accessibility level determined by the point
      --  of call" (AI05-0234) to the function. Conceptually, this belongs in
      --  Expand_Call but it couldn't be done there (because the Etype of the
      --  allocator wasn't set then) so we generate the parameter here. See
      --  the Boolean variable Defer in (a block within) Expand_Call.

      if Ada_Version >= Ada_2012 and then Nkind (Exp) = N_Function_Call then
         declare
            Subp : Entity_Id;

         begin
            if Nkind (Name (Exp)) = N_Explicit_Dereference then
               Subp := Designated_Type (Etype (Prefix (Name (Exp))));
            else
               Subp := Entity (Name (Exp));
            end if;

            Subp := Ultimate_Alias (Subp);

            if Present (Extra_Accessibility_Of_Result (Subp)) then
               Add_Extra_Actual_To_Call
                 (Subprogram_Call => Exp,
                  Extra_Formal    => Extra_Accessibility_Of_Result (Subp),
                  Extra_Actual    => Dynamic_Accessibility_Level (PtrT));
            end if;
         end;
      end if;

      --  Case of tagged type or type requiring finalization

      if Is_Tagged_Type (T) or else Needs_Finalization (T) then

         --  Ada 2005 (AI-318-02): If the initialization expression is a call
         --  to a build-in-place function, then access to the allocated object
         --  must be passed to the function.

         if Is_Build_In_Place_Function_Call (Exp) then
            Make_Build_In_Place_Call_In_Allocator (N, Exp);
            Apply_Accessibility_Check (N, Built_In_Place => True);
            return;

         --  Ada 2005 (AI-318-02): Specialization of the previous case for
         --  expressions containing a build-in-place function call whose
         --  returned object covers interface types, and Expr has calls to
         --  Ada.Tags.Displace to displace the pointer to the returned build-
         --  in-place object to reference the secondary dispatch table of a
         --  covered interface type.

         elsif Present (Unqual_BIP_Iface_Function_Call (Exp)) then
            Make_Build_In_Place_Iface_Call_In_Allocator (N, Exp);
            Apply_Accessibility_Check (N, Built_In_Place => True);
            return;
         end if;

         --  Actions inserted before:
         --    Temp : constant ptr_T := new T'(Expression);
         --    Temp._tag = T'tag;  --  when not class-wide
         --    [Deep_]Adjust (Temp.all);

         --  We analyze by hand the new internal allocator to avoid any
         --  recursion and inappropriate call to Initialize.

         --  We don't want to remove side effects when the expression must be
         --  built in place. In the case of a build-in-place function call,
         --  that could lead to a duplication of the call, which was already
         --  substituted for the allocator.

         if not Aggr_In_Place then
            Remove_Side_Effects (Exp);
         end if;

         Temp := Make_Temporary (Loc, 'P', N);

         --  For a class wide allocation generate the following code:

         --    type Equiv_Record is record ... end record;
         --    implicit subtype CW is <Class_Wide_Subytpe>;
         --    temp : PtrT := new CW'(CW!(expr));

         if Is_Class_Wide_Type (T) then
            Expand_Subtype_From_Expr (Empty, T, Indic, Exp);

            --  Ada 2005 (AI-251): If the expression is a class-wide interface
            --  object we generate code to move up "this" to reference the
            --  base of the object before allocating the new object.

            --  Note that Exp'Address is recursively expanded into a call
            --  to Base_Address (Exp.Tag)

            if Is_Class_Wide_Type (Etype (Exp))
              and then Is_Interface (Etype (Exp))
              and then Tagged_Type_Expansion
            then
               Set_Expression
                 (Expression (N),
                  Unchecked_Convert_To (Entity (Indic),
                    Make_Explicit_Dereference (Loc,
                      Unchecked_Convert_To (RTE (RE_Tag_Ptr),
                        Make_Attribute_Reference (Loc,
                          Prefix         => Exp,
                          Attribute_Name => Name_Address)))));
            else
               Set_Expression
                 (Expression (N),
                  Unchecked_Convert_To (Entity (Indic), Exp));
            end if;

            Analyze_And_Resolve (Expression (N), Entity (Indic));
         end if;

         --  Processing for allocators returning non-interface types

         if not Is_Interface (Directly_Designated_Type (PtrT)) then
            if Aggr_In_Place then
               Temp_Decl :=
                 Make_Object_Declaration (Loc,
                   Defining_Identifier => Temp,
                   Object_Definition   => New_Occurrence_Of (PtrT, Loc),
                   Expression          =>
                     Make_Allocator (Loc,
                       Expression =>
                         New_Occurrence_Of (Etype (Exp), Loc)));

               --  Copy the Comes_From_Source flag for the allocator we just
               --  built, since logically this allocator is a replacement of
               --  the original allocator node. This is for proper handling of
               --  restriction No_Implicit_Heap_Allocations.

               Set_Comes_From_Source
                 (Expression (Temp_Decl), Comes_From_Source (N));

               Set_No_Initialization (Expression (Temp_Decl));
               Insert_Action (N, Temp_Decl);

               Build_Allocate_Deallocate_Proc (Temp_Decl, True);
               Convert_Aggr_In_Allocator (N, Temp_Decl, Exp);

            else
               Node := Relocate_Node (N);
               Set_Analyzed (Node);

               Temp_Decl :=
                 Make_Object_Declaration (Loc,
                   Defining_Identifier => Temp,
                   Constant_Present    => True,
                   Object_Definition   => New_Occurrence_Of (PtrT, Loc),
                   Expression          => Node);

               Insert_Action (N, Temp_Decl);
               Build_Allocate_Deallocate_Proc (Temp_Decl, True);
            end if;

         --  Ada 2005 (AI-251): Handle allocators whose designated type is an
         --  interface type. In this case we use the type of the qualified
         --  expression to allocate the object.

         else
            declare
               Def_Id   : constant Entity_Id := Make_Temporary (Loc, 'T');
               New_Decl : Node_Id;

            begin
               New_Decl :=
                 Make_Full_Type_Declaration (Loc,
                   Defining_Identifier => Def_Id,
                   Type_Definition     =>
                     Make_Access_To_Object_Definition (Loc,
                       All_Present            => True,
                       Null_Exclusion_Present => False,
                       Constant_Present       =>
                         Is_Access_Constant (Etype (N)),
                       Subtype_Indication     =>
                         New_Occurrence_Of (Etype (Exp), Loc)));

               Insert_Action (N, New_Decl);

               --  Inherit the allocation-related attributes from the original
               --  access type.

               Set_Finalization_Master
                 (Def_Id, Finalization_Master (PtrT));

               Set_Associated_Storage_Pool
                 (Def_Id, Associated_Storage_Pool (PtrT));

               --  Declare the object using the previous type declaration

               if Aggr_In_Place then
                  Temp_Decl :=
                    Make_Object_Declaration (Loc,
                      Defining_Identifier => Temp,
                      Object_Definition   => New_Occurrence_Of (Def_Id, Loc),
                      Expression          =>
                        Make_Allocator (Loc,
                          New_Occurrence_Of (Etype (Exp), Loc)));

                  --  Copy the Comes_From_Source flag for the allocator we just
                  --  built, since logically this allocator is a replacement of
                  --  the original allocator node. This is for proper handling
                  --  of restriction No_Implicit_Heap_Allocations.

                  Set_Comes_From_Source
                    (Expression (Temp_Decl), Comes_From_Source (N));

                  Set_No_Initialization (Expression (Temp_Decl));
                  Insert_Action (N, Temp_Decl);

                  Build_Allocate_Deallocate_Proc (Temp_Decl, True);
                  Convert_Aggr_In_Allocator (N, Temp_Decl, Exp);

               else
                  Node := Relocate_Node (N);
                  Set_Analyzed (Node);

                  Temp_Decl :=
                    Make_Object_Declaration (Loc,
                      Defining_Identifier => Temp,
                      Constant_Present    => True,
                      Object_Definition   => New_Occurrence_Of (Def_Id, Loc),
                      Expression          => Node);

                  Insert_Action (N, Temp_Decl);
                  Build_Allocate_Deallocate_Proc (Temp_Decl, True);
               end if;

               --  Generate an additional object containing the address of the
               --  returned object. The type of this second object declaration
               --  is the correct type required for the common processing that
               --  is still performed by this subprogram. The displacement of
               --  this pointer to reference the component associated with the
               --  interface type will be done at the end of common processing.

               New_Decl :=
                 Make_Object_Declaration (Loc,
                   Defining_Identifier => Make_Temporary (Loc, 'P'),
                   Object_Definition   => New_Occurrence_Of (PtrT, Loc),
                   Expression          =>
                     Unchecked_Convert_To (PtrT,
                       New_Occurrence_Of (Temp, Loc)));

               Insert_Action (N, New_Decl);

               Temp_Decl := New_Decl;
               Temp      := Defining_Identifier (New_Decl);
            end;
         end if;

         --  Generate the tag assignment

         --  Suppress the tag assignment for VM targets because VM tags are
         --  represented implicitly in objects.

         if not Tagged_Type_Expansion then
            null;

         --  Ada 2005 (AI-251): Suppress the tag assignment with class-wide
         --  interface objects because in this case the tag does not change.

         elsif Is_Interface (Directly_Designated_Type (Etype (N))) then
            pragma Assert (Is_Class_Wide_Type
                            (Directly_Designated_Type (Etype (N))));
            null;

         elsif Is_Tagged_Type (T) and then not Is_Class_Wide_Type (T) then
            TagT := T;
            TagR := New_Occurrence_Of (Temp, Loc);

         elsif Is_Private_Type (T)
           and then Is_Tagged_Type (Underlying_Type (T))
         then
            TagT := Underlying_Type (T);
            TagR :=
              Unchecked_Convert_To (Underlying_Type (T),
                Make_Explicit_Dereference (Loc,
                  Prefix => New_Occurrence_Of (Temp, Loc)));
         end if;

         if Present (TagT) then
            declare
               Full_T : constant Entity_Id := Underlying_Type (TagT);

            begin
               Tag_Assign :=
                 Make_Assignment_Statement (Loc,
                   Name       =>
                     Make_Selected_Component (Loc,
                       Prefix        => TagR,
                       Selector_Name =>
                         New_Occurrence_Of
                           (First_Tag_Component (Full_T), Loc)),

                   Expression =>
                     Unchecked_Convert_To (RTE (RE_Tag),
                       New_Occurrence_Of
                         (Elists.Node
                           (First_Elmt (Access_Disp_Table (Full_T))), Loc)));
            end;

            --  The previous assignment has to be done in any case

            Set_Assignment_OK (Name (Tag_Assign));
            Insert_Action (N, Tag_Assign);
         end if;

         --  Generate an Adjust call if the object will be moved. In Ada 2005,
         --  the object may be inherently limited, in which case there is no
         --  Adjust procedure, and the object is built in place. In Ada 95, the
         --  object can be limited but not inherently limited if this allocator
         --  came from a return statement (we're allocating the result on the
         --  secondary stack). In that case, the object will be moved, so we do
         --  want to Adjust. However, if it's a nonlimited build-in-place
         --  function call, Adjust is not wanted.

         if Needs_Finalization (DesigT)
           and then Needs_Finalization (T)
           and then not Aggr_In_Place
           and then not Is_Limited_View (T)
           and then not Alloc_For_BIP_Return (N)
           and then not Is_Build_In_Place_Function_Call (Expression (N))
         then
            --  An unchecked conversion is needed in the classwide case because
            --  the designated type can be an ancestor of the subtype mark of
            --  the allocator.

            Adj_Call :=
              Make_Adjust_Call
                (Obj_Ref =>
                   Unchecked_Convert_To (T,
                     Make_Explicit_Dereference (Loc,
                       Prefix => New_Occurrence_Of (Temp, Loc))),
                 Typ     => T);

            if Present (Adj_Call) then
               Insert_Action (N, Adj_Call);
            end if;
         end if;

         --  Note: the accessibility check must be inserted after the call to
         --  [Deep_]Adjust to ensure proper completion of the assignment.

         Apply_Accessibility_Check (Temp);

         Rewrite (N, New_Occurrence_Of (Temp, Loc));
         Analyze_And_Resolve (N, PtrT);

         --  Ada 2005 (AI-251): Displace the pointer to reference the record
         --  component containing the secondary dispatch table of the interface
         --  type.

         if Is_Interface (Directly_Designated_Type (PtrT)) then
            Displace_Allocator_Pointer (N);
         end if;

      --  Always force the generation of a temporary for aggregates when
      --  generating C code, to simplify the work in the code generator.

      elsif Aggr_In_Place
        or else (Modify_Tree_For_C and then Nkind (Exp) = N_Aggregate)
      then
         Temp := Make_Temporary (Loc, 'P', N);
         Temp_Decl :=
           Make_Object_Declaration (Loc,
             Defining_Identifier => Temp,
             Object_Definition   => New_Occurrence_Of (PtrT, Loc),
             Expression          =>
               Make_Allocator (Loc,
                 Expression => New_Occurrence_Of (Etype (Exp), Loc)));

         --  Copy the Comes_From_Source flag for the allocator we just built,
         --  since logically this allocator is a replacement of the original
         --  allocator node. This is for proper handling of restriction
         --  No_Implicit_Heap_Allocations.

         Set_Comes_From_Source
           (Expression (Temp_Decl), Comes_From_Source (N));

         Set_No_Initialization (Expression (Temp_Decl));
         Insert_Action (N, Temp_Decl);

         Build_Allocate_Deallocate_Proc (Temp_Decl, True);
         Convert_Aggr_In_Allocator (N, Temp_Decl, Exp);

         Rewrite (N, New_Occurrence_Of (Temp, Loc));
         Analyze_And_Resolve (N, PtrT);

      elsif Is_Access_Type (T) and then Can_Never_Be_Null (T) then
         Install_Null_Excluding_Check (Exp);

      elsif Is_Access_Type (DesigT)
        and then Nkind (Exp) = N_Allocator
        and then Nkind (Expression (Exp)) /= N_Qualified_Expression
      then
         --  Apply constraint to designated subtype indication

         Apply_Constraint_Check
           (Expression (Exp), Designated_Type (DesigT), No_Sliding => True);

         if Nkind (Expression (Exp)) = N_Raise_Constraint_Error then

            --  Propagate constraint_error to enclosing allocator

            Rewrite (Exp, New_Copy (Expression (Exp)));
         end if;

      else
         Build_Allocate_Deallocate_Proc (N, True);

         --  If we have:
         --    type A is access T1;
         --    X : A := new T2'(...);
         --  T1 and T2 can be different subtypes, and we might need to check
         --  both constraints. First check against the type of the qualified
         --  expression.

         Apply_Constraint_Check (Exp, T, No_Sliding => True);

         if Do_Range_Check (Exp) then
            Generate_Range_Check (Exp, DesigT, CE_Range_Check_Failed);
         end if;

         --  A check is also needed in cases where the designated subtype is
         --  constrained and differs from the subtype given in the qualified
         --  expression. Note that the check on the qualified expression does
         --  not allow sliding, but this check does (a relaxation from Ada 83).

         if Is_Constrained (DesigT)
           and then not Subtypes_Statically_Match (T, DesigT)
         then
            Apply_Constraint_Check
              (Exp, DesigT, No_Sliding => False);

            if Do_Range_Check (Exp) then
               Generate_Range_Check (Exp, DesigT, CE_Range_Check_Failed);
            end if;
         end if;

         --  For an access to unconstrained packed array, GIGI needs to see an
         --  expression with a constrained subtype in order to compute the
         --  proper size for the allocator.

         if Is_Array_Type (T)
           and then not Is_Constrained (T)
           and then Is_Packed (T)
         then
            declare
               ConstrT      : constant Entity_Id := Make_Temporary (Loc, 'A');
               Internal_Exp : constant Node_Id   := Relocate_Node (Exp);
            begin
               Insert_Action (Exp,
                 Make_Subtype_Declaration (Loc,
                   Defining_Identifier => ConstrT,
                   Subtype_Indication  =>
                     Make_Subtype_From_Expr (Internal_Exp, T)));
               Freeze_Itype (ConstrT, Exp);
               Rewrite (Exp, OK_Convert_To (ConstrT, Internal_Exp));
            end;
         end if;

         --  Ada 2005 (AI-318-02): If the initialization expression is a call
         --  to a build-in-place function, then access to the allocated object
         --  must be passed to the function.

         if Is_Build_In_Place_Function_Call (Exp) then
            Make_Build_In_Place_Call_In_Allocator (N, Exp);
         end if;
      end if;

   exception
      when RE_Not_Available =>
         return;
   end Expand_Allocator_Expression;

   -----------------------------
   -- Expand_Array_Comparison --
   -----------------------------

   --  Expansion is only required in the case of array types. For the unpacked
   --  case, an appropriate runtime routine is called. For packed cases, and
   --  also in some other cases where a runtime routine cannot be called, the
   --  form of the expansion is:

   --     [body for greater_nn; boolean_expression]

   --  The body is built by Make_Array_Comparison_Op, and the form of the
   --  Boolean expression depends on the operator involved.

   procedure Expand_Array_Comparison (N : Node_Id) is
      Loc  : constant Source_Ptr := Sloc (N);
      Op1  : Node_Id             := Left_Opnd (N);
      Op2  : Node_Id             := Right_Opnd (N);
      Typ1 : constant Entity_Id  := Base_Type (Etype (Op1));
      Ctyp : constant Entity_Id  := Component_Type (Typ1);

      Expr      : Node_Id;
      Func_Body : Node_Id;
      Func_Name : Entity_Id;

      Comp : RE_Id;

      Byte_Addressable : constant Boolean := System_Storage_Unit = Byte'Size;
      --  True for byte addressable target

      function Length_Less_Than_4 (Opnd : Node_Id) return Boolean;
      --  Returns True if the length of the given operand is known to be less
      --  than 4. Returns False if this length is known to be four or greater
      --  or is not known at compile time.

      ------------------------
      -- Length_Less_Than_4 --
      ------------------------

      function Length_Less_Than_4 (Opnd : Node_Id) return Boolean is
         Otyp : constant Entity_Id := Etype (Opnd);

      begin
         if Ekind (Otyp) = E_String_Literal_Subtype then
            return String_Literal_Length (Otyp) < 4;

         else
            declare
               Ityp : constant Entity_Id := Etype (First_Index (Otyp));
               Lo   : constant Node_Id   := Type_Low_Bound (Ityp);
               Hi   : constant Node_Id   := Type_High_Bound (Ityp);
               Lov  : Uint;
               Hiv  : Uint;

            begin
               if Compile_Time_Known_Value (Lo) then
                  Lov := Expr_Value (Lo);
               else
                  return False;
               end if;

               if Compile_Time_Known_Value (Hi) then
                  Hiv := Expr_Value (Hi);
               else
                  return False;
               end if;

               return Hiv < Lov + 3;
            end;
         end if;
      end Length_Less_Than_4;

   --  Start of processing for Expand_Array_Comparison

   begin
      --  Deal first with unpacked case, where we can call a runtime routine
      --  except that we avoid this for targets for which are not addressable
      --  by bytes.

      if not Is_Bit_Packed_Array (Typ1)
        and then Byte_Addressable
      then
         --  The call we generate is:

         --  Compare_Array_xn[_Unaligned]
         --    (left'address, right'address, left'length, right'length) <op> 0

         --  x = U for unsigned, S for signed
         --  n = 8,16,32,64 for component size
         --  Add _Unaligned if length < 4 and component size is 8.
         --  <op> is the standard comparison operator

         if Component_Size (Typ1) = 8 then
            if Length_Less_Than_4 (Op1)
                 or else
               Length_Less_Than_4 (Op2)
            then
               if Is_Unsigned_Type (Ctyp) then
                  Comp := RE_Compare_Array_U8_Unaligned;
               else
                  Comp := RE_Compare_Array_S8_Unaligned;
               end if;

            else
               if Is_Unsigned_Type (Ctyp) then
                  Comp := RE_Compare_Array_U8;
               else
                  Comp := RE_Compare_Array_S8;
               end if;
            end if;

         elsif Component_Size (Typ1) = 16 then
            if Is_Unsigned_Type (Ctyp) then
               Comp := RE_Compare_Array_U16;
            else
               Comp := RE_Compare_Array_S16;
            end if;

         elsif Component_Size (Typ1) = 32 then
            if Is_Unsigned_Type (Ctyp) then
               Comp := RE_Compare_Array_U32;
            else
               Comp := RE_Compare_Array_S32;
            end if;

         else pragma Assert (Component_Size (Typ1) = 64);
            if Is_Unsigned_Type (Ctyp) then
               Comp := RE_Compare_Array_U64;
            else
               Comp := RE_Compare_Array_S64;
            end if;
         end if;

         if RTE_Available (Comp) then

            --  Expand to a call only if the runtime function is available,
            --  otherwise fall back to inline code.

            Remove_Side_Effects (Op1, Name_Req => True);
            Remove_Side_Effects (Op2, Name_Req => True);

            Rewrite (Op1,
              Make_Function_Call (Sloc (Op1),
                Name => New_Occurrence_Of (RTE (Comp), Loc),

                Parameter_Associations => New_List (
                  Make_Attribute_Reference (Loc,
                    Prefix         => Relocate_Node (Op1),
                    Attribute_Name => Name_Address),

                  Make_Attribute_Reference (Loc,
                    Prefix         => Relocate_Node (Op2),
                    Attribute_Name => Name_Address),

                  Make_Attribute_Reference (Loc,
                    Prefix         => Relocate_Node (Op1),
                    Attribute_Name => Name_Length),

                  Make_Attribute_Reference (Loc,
                    Prefix         => Relocate_Node (Op2),
                    Attribute_Name => Name_Length))));

            Rewrite (Op2,
              Make_Integer_Literal (Sloc (Op2),
                Intval => Uint_0));

            Analyze_And_Resolve (Op1, Standard_Integer);
            Analyze_And_Resolve (Op2, Standard_Integer);
            return;
         end if;
      end if;

      --  Cases where we cannot make runtime call

      --  For (a <= b) we convert to not (a > b)

      if Chars (N) = Name_Op_Le then
         Rewrite (N,
           Make_Op_Not (Loc,
             Right_Opnd =>
                Make_Op_Gt (Loc,
                 Left_Opnd  => Op1,
                 Right_Opnd => Op2)));
         Analyze_And_Resolve (N, Standard_Boolean);
         return;

      --  For < the Boolean expression is
      --    greater__nn (op2, op1)

      elsif Chars (N) = Name_Op_Lt then
         Func_Body := Make_Array_Comparison_Op (Typ1, N);

         --  Switch operands

         Op1 := Right_Opnd (N);
         Op2 := Left_Opnd  (N);

      --  For (a >= b) we convert to not (a < b)

      elsif Chars (N) = Name_Op_Ge then
         Rewrite (N,
           Make_Op_Not (Loc,
             Right_Opnd =>
               Make_Op_Lt (Loc,
                 Left_Opnd  => Op1,
                 Right_Opnd => Op2)));
         Analyze_And_Resolve (N, Standard_Boolean);
         return;

      --  For > the Boolean expression is
      --    greater__nn (op1, op2)

      else
         pragma Assert (Chars (N) = Name_Op_Gt);
         Func_Body := Make_Array_Comparison_Op (Typ1, N);
      end if;

      Func_Name := Defining_Unit_Name (Specification (Func_Body));
      Expr :=
        Make_Function_Call (Loc,
          Name => New_Occurrence_Of (Func_Name, Loc),
          Parameter_Associations => New_List (Op1, Op2));

      Insert_Action (N, Func_Body);
      Rewrite (N, Expr);
      Analyze_And_Resolve (N, Standard_Boolean);
   end Expand_Array_Comparison;

   ---------------------------
   -- Expand_Array_Equality --
   ---------------------------

   --  Expand an equality function for multi-dimensional arrays. Here is an
   --  example of such a function for Nb_Dimension = 2

   --  function Enn (A : atyp; B : btyp) return boolean is
   --  begin
   --     if (A'length (1) = 0 or else A'length (2) = 0)
   --          and then
   --        (B'length (1) = 0 or else B'length (2) = 0)
   --     then
   --        return True;    -- RM 4.5.2(22)
   --     end if;

   --     if A'length (1) /= B'length (1)
   --               or else
   --           A'length (2) /= B'length (2)
   --     then
   --        return False;   -- RM 4.5.2(23)
   --     end if;

   --     declare
   --        A1 : Index_T1 := A'first (1);
   --        B1 : Index_T1 := B'first (1);
   --     begin
   --        loop
   --           declare
   --              A2 : Index_T2 := A'first (2);
   --              B2 : Index_T2 := B'first (2);
   --           begin
   --              loop
   --                 if A (A1, A2) /= B (B1, B2) then
   --                    return False;
   --                 end if;

   --                 exit when A2 = A'last (2);
   --                 A2 := Index_T2'succ (A2);
   --                 B2 := Index_T2'succ (B2);
   --              end loop;
   --           end;

   --           exit when A1 = A'last (1);
   --           A1 := Index_T1'succ (A1);
   --           B1 := Index_T1'succ (B1);
   --        end loop;
   --     end;

   --     return true;
   --  end Enn;

   --  Note on the formal types used (atyp and btyp). If either of the arrays
   --  is of a private type, we use the underlying type, and do an unchecked
   --  conversion of the actual. If either of the arrays has a bound depending
   --  on a discriminant, then we use the base type since otherwise we have an
   --  escaped discriminant in the function.

   --  If both arrays are constrained and have the same bounds, we can generate
   --  a loop with an explicit iteration scheme using a 'Range attribute over
   --  the first array.

   function Expand_Array_Equality
     (Nod    : Node_Id;
      Lhs    : Node_Id;
      Rhs    : Node_Id;
      Bodies : List_Id;
      Typ    : Entity_Id) return Node_Id
   is
      Loc         : constant Source_Ptr := Sloc (Nod);
      Decls       : constant List_Id    := New_List;
      Index_List1 : constant List_Id    := New_List;
      Index_List2 : constant List_Id    := New_List;

      First_Idx : Node_Id;
      Formals   : List_Id;
      Func_Name : Entity_Id;
      Func_Body : Node_Id;

      A : constant Entity_Id := Make_Defining_Identifier (Loc, Name_uA);
      B : constant Entity_Id := Make_Defining_Identifier (Loc, Name_uB);

      Ltyp : Entity_Id;
      Rtyp : Entity_Id;
      --  The parameter types to be used for the formals

      New_Lhs : Node_Id;
      New_Rhs : Node_Id;
      --  The LHS and RHS converted to the parameter types

      function Arr_Attr
        (Arr : Entity_Id;
         Nam : Name_Id;
         Num : Int) return Node_Id;
      --  This builds the attribute reference Arr'Nam (Expr)

      function Component_Equality (Typ : Entity_Id) return Node_Id;
      --  Create one statement to compare corresponding components, designated
      --  by a full set of indexes.

      function Get_Arg_Type (N : Node_Id) return Entity_Id;
      --  Given one of the arguments, computes the appropriate type to be used
      --  for that argument in the corresponding function formal

      function Handle_One_Dimension
        (N     : Int;
         Index : Node_Id) return Node_Id;
      --  This procedure returns the following code
      --
      --    declare
      --       Bn : Index_T := B'First (N);
      --    begin
      --       loop
      --          xxx
      --          exit when An = A'Last (N);
      --          An := Index_T'Succ (An)
      --          Bn := Index_T'Succ (Bn)
      --       end loop;
      --    end;
      --
      --  If both indexes are constrained and identical, the procedure
      --  returns a simpler loop:
      --
      --      for An in A'Range (N) loop
      --         xxx
      --      end loop
      --
      --  N is the dimension for which we are generating a loop. Index is the
      --  N'th index node, whose Etype is Index_Type_n in the above code. The
      --  xxx statement is either the loop or declare for the next dimension
      --  or if this is the last dimension the comparison of corresponding
      --  components of the arrays.
      --
      --  The actual way the code works is to return the comparison of
      --  corresponding components for the N+1 call. That's neater.

      function Test_Empty_Arrays return Node_Id;
      --  This function constructs the test for both arrays being empty
      --    (A'length (1) = 0 or else A'length (2) = 0 or else ...)
      --      and then
      --    (B'length (1) = 0 or else B'length (2) = 0 or else ...)

      function Test_Lengths_Correspond return Node_Id;
      --  This function constructs the test for arrays having different lengths
      --  in at least one index position, in which case the resulting code is:

      --     A'length (1) /= B'length (1)
      --       or else
      --     A'length (2) /= B'length (2)
      --       or else
      --       ...

      --------------
      -- Arr_Attr --
      --------------

      function Arr_Attr
        (Arr : Entity_Id;
         Nam : Name_Id;
         Num : Int) return Node_Id
      is
      begin
         return
           Make_Attribute_Reference (Loc,
             Attribute_Name => Nam,
             Prefix         => New_Occurrence_Of (Arr, Loc),
             Expressions    => New_List (Make_Integer_Literal (Loc, Num)));
      end Arr_Attr;

      ------------------------
      -- Component_Equality --
      ------------------------

      function Component_Equality (Typ : Entity_Id) return Node_Id is
         Test : Node_Id;
         L, R : Node_Id;

      begin
         --  if a(i1...) /= b(j1...) then return false; end if;

         L :=
           Make_Indexed_Component (Loc,
             Prefix      => Make_Identifier (Loc, Chars (A)),
             Expressions => Index_List1);

         R :=
           Make_Indexed_Component (Loc,
             Prefix      => Make_Identifier (Loc, Chars (B)),
             Expressions => Index_List2);

         Test := Expand_Composite_Equality
                   (Nod, Component_Type (Typ), L, R, Decls);

         --  If some (sub)component is an unchecked_union, the whole operation
         --  will raise program error.

         if Nkind (Test) = N_Raise_Program_Error then

            --  This node is going to be inserted at a location where a
            --  statement is expected: clear its Etype so analysis will set
            --  it to the expected Standard_Void_Type.

            Set_Etype (Test, Empty);
            return Test;

         else
            return
              Make_Implicit_If_Statement (Nod,
                Condition       => Make_Op_Not (Loc, Right_Opnd => Test),
                Then_Statements => New_List (
                  Make_Simple_Return_Statement (Loc,
                    Expression => New_Occurrence_Of (Standard_False, Loc))));
         end if;
      end Component_Equality;

      ------------------
      -- Get_Arg_Type --
      ------------------

      function Get_Arg_Type (N : Node_Id) return Entity_Id is
         T : Entity_Id;
         X : Node_Id;

      begin
         T := Etype (N);

         if No (T) then
            return Typ;

         else
            T := Underlying_Type (T);

            X := First_Index (T);
            while Present (X) loop
               if Denotes_Discriminant (Type_Low_Bound  (Etype (X)))
                    or else
                  Denotes_Discriminant (Type_High_Bound (Etype (X)))
               then
                  T := Base_Type (T);
                  exit;
               end if;

               Next_Index (X);
            end loop;

            return T;
         end if;
      end Get_Arg_Type;

      --------------------------
      -- Handle_One_Dimension --
      ---------------------------

      function Handle_One_Dimension
        (N     : Int;
         Index : Node_Id) return Node_Id
      is
         Need_Separate_Indexes : constant Boolean :=
           Ltyp /= Rtyp or else not Is_Constrained (Ltyp);
         --  If the index types are identical, and we are working with
         --  constrained types, then we can use the same index for both
         --  of the arrays.

         An : constant Entity_Id := Make_Temporary (Loc, 'A');

         Bn       : Entity_Id;
         Index_T  : Entity_Id;
         Stm_List : List_Id;
         Loop_Stm : Node_Id;

      begin
         if N > Number_Dimensions (Ltyp) then
            return Component_Equality (Ltyp);
         end if;

         --  Case where we generate a loop

         Index_T := Base_Type (Etype (Index));

         if Need_Separate_Indexes then
            Bn := Make_Temporary (Loc, 'B');
         else
            Bn := An;
         end if;

         Append (New_Occurrence_Of (An, Loc), Index_List1);
         Append (New_Occurrence_Of (Bn, Loc), Index_List2);

         Stm_List := New_List (
           Handle_One_Dimension (N + 1, Next_Index (Index)));

         if Need_Separate_Indexes then

            --  Generate guard for loop, followed by increments of indexes

            Append_To (Stm_List,
               Make_Exit_Statement (Loc,
                 Condition =>
                   Make_Op_Eq (Loc,
                      Left_Opnd  => New_Occurrence_Of (An, Loc),
                      Right_Opnd => Arr_Attr (A, Name_Last, N))));

            Append_To (Stm_List,
              Make_Assignment_Statement (Loc,
                Name       => New_Occurrence_Of (An, Loc),
                Expression =>
                  Make_Attribute_Reference (Loc,
                    Prefix         => New_Occurrence_Of (Index_T, Loc),
                    Attribute_Name => Name_Succ,
                    Expressions    => New_List (
                      New_Occurrence_Of (An, Loc)))));

            Append_To (Stm_List,
              Make_Assignment_Statement (Loc,
                Name       => New_Occurrence_Of (Bn, Loc),
                Expression =>
                  Make_Attribute_Reference (Loc,
                    Prefix         => New_Occurrence_Of (Index_T, Loc),
                    Attribute_Name => Name_Succ,
                    Expressions    => New_List (
                      New_Occurrence_Of (Bn, Loc)))));
         end if;

         --  If separate indexes, we need a declare block for An and Bn, and a
         --  loop without an iteration scheme.

         if Need_Separate_Indexes then
            Loop_Stm :=
              Make_Implicit_Loop_Statement (Nod, Statements => Stm_List);

            return
              Make_Block_Statement (Loc,
                Declarations => New_List (
                  Make_Object_Declaration (Loc,
                    Defining_Identifier => An,
                    Object_Definition   => New_Occurrence_Of (Index_T, Loc),
                    Expression          => Arr_Attr (A, Name_First, N)),

                  Make_Object_Declaration (Loc,
                    Defining_Identifier => Bn,
                    Object_Definition   => New_Occurrence_Of (Index_T, Loc),
                    Expression          => Arr_Attr (B, Name_First, N))),

                Handled_Statement_Sequence =>
                  Make_Handled_Sequence_Of_Statements (Loc,
                    Statements => New_List (Loop_Stm)));

         --  If no separate indexes, return loop statement with explicit
         --  iteration scheme on its own.

         else
            Loop_Stm :=
              Make_Implicit_Loop_Statement (Nod,
                Statements       => Stm_List,
                Iteration_Scheme =>
                  Make_Iteration_Scheme (Loc,
                    Loop_Parameter_Specification =>
                      Make_Loop_Parameter_Specification (Loc,
                        Defining_Identifier         => An,
                        Discrete_Subtype_Definition =>
                          Arr_Attr (A, Name_Range, N))));
            return Loop_Stm;
         end if;
      end Handle_One_Dimension;

      -----------------------
      -- Test_Empty_Arrays --
      -----------------------

      function Test_Empty_Arrays return Node_Id is
         Alist : Node_Id;
         Blist : Node_Id;

         Atest : Node_Id;
         Btest : Node_Id;

      begin
         Alist := Empty;
         Blist := Empty;
         for J in 1 .. Number_Dimensions (Ltyp) loop
            Atest :=
              Make_Op_Eq (Loc,
                Left_Opnd  => Arr_Attr (A, Name_Length, J),
                Right_Opnd => Make_Integer_Literal (Loc, 0));

            Btest :=
              Make_Op_Eq (Loc,
                Left_Opnd  => Arr_Attr (B, Name_Length, J),
                Right_Opnd => Make_Integer_Literal (Loc, 0));

            if No (Alist) then
               Alist := Atest;
               Blist := Btest;

            else
               Alist :=
                 Make_Or_Else (Loc,
                   Left_Opnd  => Relocate_Node (Alist),
                   Right_Opnd => Atest);

               Blist :=
                 Make_Or_Else (Loc,
                   Left_Opnd  => Relocate_Node (Blist),
                   Right_Opnd => Btest);
            end if;
         end loop;

         return
           Make_And_Then (Loc,
             Left_Opnd  => Alist,
             Right_Opnd => Blist);
      end Test_Empty_Arrays;

      -----------------------------
      -- Test_Lengths_Correspond --
      -----------------------------

      function Test_Lengths_Correspond return Node_Id is
         Result : Node_Id;
         Rtest  : Node_Id;

      begin
         Result := Empty;
         for J in 1 .. Number_Dimensions (Ltyp) loop
            Rtest :=
              Make_Op_Ne (Loc,
                Left_Opnd  => Arr_Attr (A, Name_Length, J),
                Right_Opnd => Arr_Attr (B, Name_Length, J));

            if No (Result) then
               Result := Rtest;
            else
               Result :=
                 Make_Or_Else (Loc,
                   Left_Opnd  => Relocate_Node (Result),
                   Right_Opnd => Rtest);
            end if;
         end loop;

         return Result;
      end Test_Lengths_Correspond;

   --  Start of processing for Expand_Array_Equality

   begin
      Ltyp := Get_Arg_Type (Lhs);
      Rtyp := Get_Arg_Type (Rhs);

      --  For now, if the argument types are not the same, go to the base type,
      --  since the code assumes that the formals have the same type. This is
      --  fixable in future ???

      if Ltyp /= Rtyp then
         Ltyp := Base_Type (Ltyp);
         Rtyp := Base_Type (Rtyp);
         pragma Assert (Ltyp = Rtyp);
      end if;

      --  If the array type is distinct from the type of the arguments, it
      --  is the full view of a private type. Apply an unchecked conversion
      --  to ensure that analysis of the code below succeeds.

      if No (Etype (Lhs))
        or else Base_Type (Etype (Lhs)) /= Base_Type (Ltyp)
      then
         New_Lhs := OK_Convert_To (Ltyp, Lhs);
      else
         New_Lhs := Lhs;
      end if;

      if No (Etype (Rhs))
        or else Base_Type (Etype (Rhs)) /= Base_Type (Rtyp)
      then
         New_Rhs := OK_Convert_To (Rtyp, Rhs);
      else
         New_Rhs := Rhs;
      end if;

      First_Idx := First_Index (Ltyp);

      --  If optimization is enabled and the array boils down to a couple of
      --  consecutive elements, generate a simple conjunction of comparisons
      --  which should be easier to optimize by the code generator.

      if Optimization_Level > 0
        and then Ltyp = Rtyp
        and then Is_Constrained (Ltyp)
        and then Number_Dimensions (Ltyp) = 1
        and then Nkind (First_Idx) = N_Range
        and then Compile_Time_Known_Value (Low_Bound (First_Idx))
        and then Compile_Time_Known_Value (High_Bound (First_Idx))
        and then Expr_Value (High_Bound (First_Idx)) =
                                         Expr_Value (Low_Bound (First_Idx)) + 1
      then
         declare
            Ctyp         : constant Entity_Id := Component_Type (Ltyp);
            L, R         : Node_Id;
            TestL, TestH : Node_Id;
            Index_List   : List_Id;

         begin
            Index_List := New_List (New_Copy_Tree (Low_Bound (First_Idx)));

            L :=
              Make_Indexed_Component (Loc,
                Prefix      => New_Copy_Tree (New_Lhs),
                Expressions => Index_List);

            R :=
              Make_Indexed_Component (Loc,
                Prefix      => New_Copy_Tree (New_Rhs),
                Expressions => Index_List);

            TestL := Expand_Composite_Equality (Nod, Ctyp, L, R, Bodies);

            Index_List := New_List (New_Copy_Tree (High_Bound (First_Idx)));

            L :=
              Make_Indexed_Component (Loc,
                Prefix      => New_Lhs,
                Expressions => Index_List);

            R :=
              Make_Indexed_Component (Loc,
                Prefix      => New_Rhs,
                Expressions => Index_List);

            TestH := Expand_Composite_Equality (Nod, Ctyp, L, R, Bodies);

            return
              Make_And_Then (Loc, Left_Opnd => TestL, Right_Opnd => TestH);
         end;
      end if;

      --  Build list of formals for function

      Formals := New_List (
        Make_Parameter_Specification (Loc,
          Defining_Identifier => A,
          Parameter_Type      => New_Occurrence_Of (Ltyp, Loc)),

        Make_Parameter_Specification (Loc,
          Defining_Identifier => B,
          Parameter_Type      => New_Occurrence_Of (Rtyp, Loc)));

      Func_Name := Make_Temporary (Loc, 'E');

      --  Build statement sequence for function

      Func_Body :=
        Make_Subprogram_Body (Loc,
          Specification =>
            Make_Function_Specification (Loc,
              Defining_Unit_Name       => Func_Name,
              Parameter_Specifications => Formals,
              Result_Definition => New_Occurrence_Of (Standard_Boolean, Loc)),

          Declarations => Decls,

          Handled_Statement_Sequence =>
            Make_Handled_Sequence_Of_Statements (Loc,
              Statements => New_List (

                Make_Implicit_If_Statement (Nod,
                  Condition       => Test_Empty_Arrays,
                  Then_Statements => New_List (
                    Make_Simple_Return_Statement (Loc,
                      Expression =>
                        New_Occurrence_Of (Standard_True, Loc)))),

                Make_Implicit_If_Statement (Nod,
                  Condition       => Test_Lengths_Correspond,
                  Then_Statements => New_List (
                    Make_Simple_Return_Statement (Loc,
                      Expression => New_Occurrence_Of (Standard_False, Loc)))),

                Handle_One_Dimension (1, First_Idx),

                Make_Simple_Return_Statement (Loc,
                  Expression => New_Occurrence_Of (Standard_True, Loc)))));

      Set_Has_Completion (Func_Name, True);
      Set_Is_Inlined (Func_Name);

      Append_To (Bodies, Func_Body);

      return
        Make_Function_Call (Loc,
          Name                   => New_Occurrence_Of (Func_Name, Loc),
          Parameter_Associations => New_List (New_Lhs, New_Rhs));
   end Expand_Array_Equality;

   -----------------------------
   -- Expand_Boolean_Operator --
   -----------------------------

   --  Note that we first get the actual subtypes of the operands, since we
   --  always want to deal with types that have bounds.

   procedure Expand_Boolean_Operator (N : Node_Id) is
      Typ : constant Entity_Id  := Etype (N);

   begin
      --  Special case of bit packed array where both operands are known to be
      --  properly aligned. In this case we use an efficient run time routine
      --  to carry out the operation (see System.Bit_Ops).

      if Is_Bit_Packed_Array (Typ)
        and then not Is_Possibly_Unaligned_Object (Left_Opnd (N))
        and then not Is_Possibly_Unaligned_Object (Right_Opnd (N))
      then
         Expand_Packed_Boolean_Operator (N);
         return;
      end if;

      --  For the normal non-packed case, the general expansion is to build
      --  function for carrying out the comparison (use Make_Boolean_Array_Op)
      --  and then inserting it into the tree. The original operator node is
      --  then rewritten as a call to this function. We also use this in the
      --  packed case if either operand is a possibly unaligned object.

      declare
         Loc       : constant Source_Ptr := Sloc (N);
         L         : constant Node_Id    := Relocate_Node (Left_Opnd  (N));
         R         : Node_Id             := Relocate_Node (Right_Opnd (N));
         Func_Body : Node_Id;
         Func_Name : Entity_Id;

      begin
         Convert_To_Actual_Subtype (L);
         Convert_To_Actual_Subtype (R);
         Ensure_Defined (Etype (L), N);
         Ensure_Defined (Etype (R), N);
         Apply_Length_Check (R, Etype (L));

         if Nkind (N) = N_Op_Xor then
            R := Duplicate_Subexpr (R);
            Silly_Boolean_Array_Xor_Test (N, R, Etype (L));
         end if;

         if Nkind (Parent (N)) = N_Assignment_Statement
           and then Safe_In_Place_Array_Op (Name (Parent (N)), L, R)
         then
            Build_Boolean_Array_Proc_Call (Parent (N), L, R);

         elsif Nkind (Parent (N)) = N_Op_Not
           and then Nkind (N) = N_Op_And
           and then Nkind (Parent (Parent (N))) = N_Assignment_Statement
           and then Safe_In_Place_Array_Op (Name (Parent (Parent (N))), L, R)
         then
            return;
         else

            Func_Body := Make_Boolean_Array_Op (Etype (L), N);
            Func_Name := Defining_Unit_Name (Specification (Func_Body));
            Insert_Action (N, Func_Body);

            --  Now rewrite the expression with a call

            Rewrite (N,
              Make_Function_Call (Loc,
                Name                   => New_Occurrence_Of (Func_Name, Loc),
                Parameter_Associations =>
                  New_List (
                    L,
                    Make_Type_Conversion
                      (Loc, New_Occurrence_Of (Etype (L), Loc), R))));

            Analyze_And_Resolve (N, Typ);
         end if;
      end;
   end Expand_Boolean_Operator;

   ------------------------------------------------
   -- Expand_Compare_Minimize_Eliminate_Overflow --
   ------------------------------------------------

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

      Result_Type : constant Entity_Id := Etype (N);
      --  Capture result type (could be a derived boolean type)

      Llo, Lhi : Uint;
      Rlo, Rhi : Uint;

      LLIB : constant Entity_Id := Base_Type (Standard_Long_Long_Integer);
      --  Entity for Long_Long_Integer'Base

      Check : constant Overflow_Mode_Type := Overflow_Check_Mode;
      --  Current overflow checking mode

      procedure Set_True;
      procedure Set_False;
      --  These procedures rewrite N with an occurrence of Standard_True or
      --  Standard_False, and then makes a call to Warn_On_Known_Condition.

      ---------------
      -- Set_False --
      ---------------

      procedure Set_False is
      begin
         Rewrite (N, New_Occurrence_Of (Standard_False, Loc));
         Warn_On_Known_Condition (N);
      end Set_False;

      --------------
      -- Set_True --
      --------------

      procedure Set_True is
      begin
         Rewrite (N, New_Occurrence_Of (Standard_True, Loc));
         Warn_On_Known_Condition (N);
      end Set_True;

   --  Start of processing for Expand_Compare_Minimize_Eliminate_Overflow

   begin
      --  Nothing to do unless we have a comparison operator with operands
      --  that are signed integer types, and we are operating in either
      --  MINIMIZED or ELIMINATED overflow checking mode.

      if Nkind (N) not in N_Op_Compare
        or else Check not in Minimized_Or_Eliminated
        or else not Is_Signed_Integer_Type (Etype (Left_Opnd (N)))
      then
         return;
      end if;

      --  OK, this is the case we are interested in. First step is to process
      --  our operands using the Minimize_Eliminate circuitry which applies
      --  this processing to the two operand subtrees.

      Minimize_Eliminate_Overflows
        (Left_Opnd (N),  Llo, Lhi, Top_Level => False);
      Minimize_Eliminate_Overflows
        (Right_Opnd (N), Rlo, Rhi, Top_Level => False);

      --  See if the range information decides the result of the comparison.
      --  We can only do this if we in fact have full range information (which
      --  won't be the case if either operand is bignum at this stage).

      if Llo /= No_Uint and then Rlo /= No_Uint then
         case N_Op_Compare (Nkind (N)) is
            when N_Op_Eq =>
               if Llo = Lhi and then Rlo = Rhi and then Llo = Rlo then
                  Set_True;
               elsif Llo > Rhi or else Lhi < Rlo then
                  Set_False;
               end if;

            when N_Op_Ge =>
               if Llo >= Rhi then
                  Set_True;
               elsif Lhi < Rlo then
                  Set_False;
               end if;

            when N_Op_Gt =>
               if Llo > Rhi then
                  Set_True;
               elsif Lhi <= Rlo then
                  Set_False;
               end if;

            when N_Op_Le =>
               if Llo > Rhi then
                  Set_False;
               elsif Lhi <= Rlo then
                  Set_True;
               end if;

            when N_Op_Lt =>
               if Llo >= Rhi then
                  Set_False;
               elsif Lhi < Rlo then
                  Set_True;
               end if;

            when N_Op_Ne =>
               if Llo = Lhi and then Rlo = Rhi and then Llo = Rlo then
                  Set_False;
               elsif Llo > Rhi or else Lhi < Rlo then
                  Set_True;
               end if;
         end case;

         --  All done if we did the rewrite

         if Nkind (N) not in N_Op_Compare then
            return;
         end if;
      end if;

      --  Otherwise, time to do the comparison

      declare
         Ltype : constant Entity_Id := Etype (Left_Opnd (N));
         Rtype : constant Entity_Id := Etype (Right_Opnd (N));

      begin
         --  If the two operands have the same signed integer type we are
         --  all set, nothing more to do. This is the case where either
         --  both operands were unchanged, or we rewrote both of them to
         --  be Long_Long_Integer.

         --  Note: Entity for the comparison may be wrong, but it's not worth
         --  the effort to change it, since the back end does not use it.

         if Is_Signed_Integer_Type (Ltype)
           and then Base_Type (Ltype) = Base_Type (Rtype)
         then
            return;

         --  Here if bignums are involved (can only happen in ELIMINATED mode)

         elsif Is_RTE (Ltype, RE_Bignum) or else Is_RTE (Rtype, RE_Bignum) then
            declare
               Left  : Node_Id := Left_Opnd (N);
               Right : Node_Id := Right_Opnd (N);
               --  Bignum references for left and right operands

            begin
               if not Is_RTE (Ltype, RE_Bignum) then
                  Left := Convert_To_Bignum (Left);
               elsif not Is_RTE (Rtype, RE_Bignum) then
                  Right := Convert_To_Bignum (Right);
               end if;

               --  We rewrite our node with:

               --    do
               --       Bnn : Result_Type;
               --       declare
               --          M : Mark_Id := SS_Mark;
               --       begin
               --          Bnn := Big_xx (Left, Right); (xx = EQ, NT etc)
               --          SS_Release (M);
               --       end;
               --    in
               --       Bnn
               --    end

               declare
                  Blk : constant Node_Id   := Make_Bignum_Block (Loc);
                  Bnn : constant Entity_Id := Make_Temporary (Loc, 'B', N);
                  Ent : RE_Id;

               begin
                  case N_Op_Compare (Nkind (N)) is
                     when N_Op_Eq => Ent := RE_Big_EQ;
                     when N_Op_Ge => Ent := RE_Big_GE;
                     when N_Op_Gt => Ent := RE_Big_GT;
                     when N_Op_Le => Ent := RE_Big_LE;
                     when N_Op_Lt => Ent := RE_Big_LT;
                     when N_Op_Ne => Ent := RE_Big_NE;
                  end case;

                  --  Insert assignment to Bnn into the bignum block

                  Insert_Before
                    (First (Statements (Handled_Statement_Sequence (Blk))),
                     Make_Assignment_Statement (Loc,
                       Name       => New_Occurrence_Of (Bnn, Loc),
                       Expression =>
                         Make_Function_Call (Loc,
                           Name                   =>
                             New_Occurrence_Of (RTE (Ent), Loc),
                           Parameter_Associations => New_List (Left, Right))));

                  --  Now do the rewrite with expression actions

                  Rewrite (N,
                    Make_Expression_With_Actions (Loc,
                      Actions    => New_List (
                        Make_Object_Declaration (Loc,
                          Defining_Identifier => Bnn,
                          Object_Definition   =>
                            New_Occurrence_Of (Result_Type, Loc)),
                        Blk),
                      Expression => New_Occurrence_Of (Bnn, Loc)));
                  Analyze_And_Resolve (N, Result_Type);
               end;
            end;

         --  No bignums involved, but types are different, so we must have
         --  rewritten one of the operands as a Long_Long_Integer but not
         --  the other one.

         --  If left operand is Long_Long_Integer, convert right operand
         --  and we are done (with a comparison of two Long_Long_Integers).

         elsif Ltype = LLIB then
            Convert_To_And_Rewrite (LLIB, Right_Opnd (N));
            Analyze_And_Resolve (Right_Opnd (N), LLIB, Suppress => All_Checks);
            return;

         --  If right operand is Long_Long_Integer, convert left operand
         --  and we are done (with a comparison of two Long_Long_Integers).

         --  This is the only remaining possibility

         else pragma Assert (Rtype = LLIB);
            Convert_To_And_Rewrite (LLIB, Left_Opnd (N));
            Analyze_And_Resolve (Left_Opnd (N), LLIB, Suppress => All_Checks);
            return;
         end if;
      end;
   end Expand_Compare_Minimize_Eliminate_Overflow;

   -------------------------------
   -- Expand_Composite_Equality --
   -------------------------------

   --  This function is only called for comparing internal fields of composite
   --  types when these fields are themselves composites. This is a special
   --  case because it is not possible to respect normal Ada visibility rules.

   function Expand_Composite_Equality
     (Nod    : Node_Id;
      Typ    : Entity_Id;
      Lhs    : Node_Id;
      Rhs    : Node_Id;
      Bodies : List_Id) return Node_Id
   is
      Loc       : constant Source_Ptr := Sloc (Nod);
      Full_Type : Entity_Id;
      Eq_Op     : Entity_Id;

   --  Start of processing for Expand_Composite_Equality

   begin
      if Is_Private_Type (Typ) then
         Full_Type := Underlying_Type (Typ);
      else
         Full_Type := Typ;
      end if;

      --  If the private type has no completion the context may be the
      --  expansion of a composite equality for a composite type with some
      --  still incomplete components. The expression will not be analyzed
      --  until the enclosing type is completed, at which point this will be
      --  properly expanded, unless there is a bona fide completion error.

      if No (Full_Type) then
         return Make_Op_Eq (Loc, Left_Opnd => Lhs, Right_Opnd => Rhs);
      end if;

      Full_Type := Base_Type (Full_Type);

      --  When the base type itself is private, use the full view to expand
      --  the composite equality.

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

      --  Case of array types

      if Is_Array_Type (Full_Type) then

         --  If the operand is an elementary type other than a floating-point
         --  type, then we can simply use the built-in block bitwise equality,
         --  since the predefined equality operators always apply and bitwise
         --  equality is fine for all these cases.

         if Is_Elementary_Type (Component_Type (Full_Type))
           and then not Is_Floating_Point_Type (Component_Type (Full_Type))
         then
            return Make_Op_Eq (Loc, Left_Opnd => Lhs, Right_Opnd => Rhs);

         --  For composite component types, and floating-point types, use the
         --  expansion. This deals with tagged component types (where we use
         --  the applicable equality routine) and floating-point (where we
         --  need to worry about negative zeroes), and also the case of any
         --  composite type recursively containing such fields.

         else
            declare
               Comp_Typ : Entity_Id;
               Hi       : Node_Id;
               Indx     : Node_Id;
               Ityp     : Entity_Id;
               Lo       : Node_Id;

            begin
               --  Do the comparison in the type (or its full view) and not in
               --  its unconstrained base type, because the latter operation is
               --  more complex and would also require an unchecked conversion.

               if Is_Private_Type (Typ) then
                  Comp_Typ := Underlying_Type (Typ);
               else
                  Comp_Typ := Typ;
               end if;

               --  Except for the case where the bounds of the type depend on a
               --  discriminant, or else we would run into scoping issues.

               Indx := First_Index (Comp_Typ);
               while Present (Indx) loop
                  Ityp := Etype (Indx);

                  Lo := Type_Low_Bound (Ityp);
                  Hi := Type_High_Bound (Ityp);

                  if (Nkind (Lo) = N_Identifier
                       and then Ekind (Entity (Lo)) = E_Discriminant)
                    or else
                     (Nkind (Hi) = N_Identifier
                       and then Ekind (Entity (Hi)) = E_Discriminant)
                  then
                     Comp_Typ := Full_Type;
                     exit;
                  end if;

                  Next_Index (Indx);
               end loop;

               return Expand_Array_Equality (Nod, Lhs, Rhs, Bodies, Comp_Typ);
            end;
         end if;

      --  Case of tagged record types

      elsif Is_Tagged_Type (Full_Type) then
         Eq_Op := Find_Primitive_Eq (Typ);
         pragma Assert (Present (Eq_Op));

         return
           Make_Function_Call (Loc,
             Name => New_Occurrence_Of (Eq_Op, Loc),
             Parameter_Associations =>
               New_List
                 (Unchecked_Convert_To (Etype (First_Formal (Eq_Op)), Lhs),
                  Unchecked_Convert_To (Etype (First_Formal (Eq_Op)), Rhs)));

      --  Case of untagged record types

      elsif Is_Record_Type (Full_Type) then
         Eq_Op := TSS (Full_Type, TSS_Composite_Equality);

         if Present (Eq_Op) then
            if Etype (First_Formal (Eq_Op)) /= Full_Type then

               --  Inherited equality from parent type. Convert the actuals to
               --  match signature of operation.

               declare
                  T : constant Entity_Id := Etype (First_Formal (Eq_Op));

               begin
                  return
                    Make_Function_Call (Loc,
                      Name                  => New_Occurrence_Of (Eq_Op, Loc),
                      Parameter_Associations => New_List (
                        OK_Convert_To (T, Lhs),
                        OK_Convert_To (T, Rhs)));
               end;

            else
               --  Comparison between Unchecked_Union components

               if Is_Unchecked_Union (Full_Type) then
                  declare
                     Lhs_Type      : Node_Id := Full_Type;
                     Rhs_Type      : Node_Id := Full_Type;
                     Lhs_Discr_Val : Node_Id;
                     Rhs_Discr_Val : Node_Id;

                  begin
                     --  Lhs subtype

                     if Nkind (Lhs) = N_Selected_Component then
                        Lhs_Type := Etype (Entity (Selector_Name (Lhs)));
                     end if;

                     --  Rhs subtype

                     if Nkind (Rhs) = N_Selected_Component then
                        Rhs_Type := Etype (Entity (Selector_Name (Rhs)));
                     end if;

                     --  Lhs of the composite equality

                     if Is_Constrained (Lhs_Type) then

                        --  Since the enclosing record type can never be an
                        --  Unchecked_Union (this code is executed for records
                        --  that do not have variants), we may reference its
                        --  discriminant(s).

                        if Nkind (Lhs) = N_Selected_Component
                          and then Has_Per_Object_Constraint
                                     (Entity (Selector_Name (Lhs)))
                        then
                           Lhs_Discr_Val :=
                             Make_Selected_Component (Loc,
                               Prefix        => Prefix (Lhs),
                               Selector_Name =>
                                 New_Copy
                                   (Get_Discriminant_Value
                                      (First_Discriminant (Lhs_Type),
                                       Lhs_Type,
                                       Stored_Constraint (Lhs_Type))));

                        else
                           Lhs_Discr_Val :=
                             New_Copy
                               (Get_Discriminant_Value
                                  (First_Discriminant (Lhs_Type),
                                   Lhs_Type,
                                   Stored_Constraint (Lhs_Type)));

                        end if;
                     else
                        --  It is not possible to infer the discriminant since
                        --  the subtype is not constrained.

                        return
                          Make_Raise_Program_Error (Loc,
                            Reason => PE_Unchecked_Union_Restriction);
                     end if;

                     --  Rhs of the composite equality

                     if Is_Constrained (Rhs_Type) then
                        if Nkind (Rhs) = N_Selected_Component
                          and then Has_Per_Object_Constraint
                                     (Entity (Selector_Name (Rhs)))
                        then
                           Rhs_Discr_Val :=
                             Make_Selected_Component (Loc,
                               Prefix        => Prefix (Rhs),
                               Selector_Name =>
                                 New_Copy
                                   (Get_Discriminant_Value
                                      (First_Discriminant (Rhs_Type),
                                       Rhs_Type,
                                       Stored_Constraint (Rhs_Type))));

                        else
                           Rhs_Discr_Val :=
                             New_Copy
                               (Get_Discriminant_Value
                                  (First_Discriminant (Rhs_Type),
                                   Rhs_Type,
                                   Stored_Constraint (Rhs_Type)));

                        end if;
                     else
                        return
                          Make_Raise_Program_Error (Loc,
                            Reason => PE_Unchecked_Union_Restriction);
                     end if;

                     --  Call the TSS equality function with the inferred
                     --  discriminant values.

                     return
                       Make_Function_Call (Loc,
                         Name => New_Occurrence_Of (Eq_Op, Loc),
                         Parameter_Associations => New_List (
                           Lhs,
                           Rhs,
                           Lhs_Discr_Val,
                           Rhs_Discr_Val));
                  end;

               --  All cases other than comparing Unchecked_Union types

               else
                  declare
                     T : constant Entity_Id := Etype (First_Formal (Eq_Op));
                  begin
                     return
                       Make_Function_Call (Loc,
                         Name                   =>
                           New_Occurrence_Of (Eq_Op, Loc),
                         Parameter_Associations => New_List (
                           OK_Convert_To (T, Lhs),
                           OK_Convert_To (T, Rhs)));
                  end;
               end if;
            end if;

         --  Equality composes in Ada 2012 for untagged record types. It also
         --  composes for bounded strings, because they are part of the
         --  predefined environment. We could make it compose for bounded
         --  strings by making them tagged, or by making sure all subcomponents
         --  are set to the same value, even when not used. Instead, we have
         --  this special case in the compiler, because it's more efficient.

         elsif Ada_Version >= Ada_2012 or else Is_Bounded_String (Typ) then

            --  If no TSS has been created for the type, check whether there is
            --  a primitive equality declared for it.

            declare
               Op : constant Node_Id := Build_Eq_Call (Typ, Loc, Lhs, Rhs);

            begin
               --  Use user-defined primitive if it exists, otherwise use
               --  predefined equality.

               if Present (Op) then
                  return Op;
               else
                  return Make_Op_Eq (Loc, Lhs, Rhs);
               end if;
            end;

         else
            return Expand_Record_Equality (Nod, Full_Type, Lhs, Rhs, Bodies);
         end if;

      --  Non-composite types (always use predefined equality)

      else
         return Make_Op_Eq (Loc, Left_Opnd => Lhs, Right_Opnd => Rhs);
      end if;
   end Expand_Composite_Equality;

   ------------------------
   -- Expand_Concatenate --
   ------------------------

   procedure Expand_Concatenate (Cnode : Node_Id; Opnds : List_Id) is
      Loc : constant Source_Ptr := Sloc (Cnode);

      Atyp : constant Entity_Id := Base_Type (Etype (Cnode));
      --  Result type of concatenation

      Ctyp : constant Entity_Id := Base_Type (Component_Type (Etype (Cnode)));
      --  Component type. Elements of this component type can appear as one
      --  of the operands of concatenation as well as arrays.

      Istyp : constant Entity_Id := Etype (First_Index (Atyp));
      --  Index subtype

      Ityp : constant Entity_Id := Base_Type (Istyp);
      --  Index type. This is the base type of the index subtype, and is used
      --  for all computed bounds (which may be out of range of Istyp in the
      --  case of null ranges).

      Artyp : Entity_Id;
      --  This is the type we use to do arithmetic to compute the bounds and
      --  lengths of operands. The choice of this type is a little subtle and
      --  is discussed in a separate section at the start of the body code.

      Concatenation_Error : exception;
      --  Raised if concatenation is sure to raise a CE

      Result_May_Be_Null : Boolean := True;
      --  Reset to False if at least one operand is encountered which is known
      --  at compile time to be non-null. Used for handling the special case
      --  of setting the high bound to the last operand high bound for a null
      --  result, thus ensuring a proper high bound in the super-flat case.

      N : constant Nat := List_Length (Opnds);
      --  Number of concatenation operands including possibly null operands

      NN : Nat := 0;
      --  Number of operands excluding any known to be null, except that the
      --  last operand is always retained, in case it provides the bounds for
      --  a null result.

      Opnd : Node_Id := Empty;
      --  Current operand being processed in the loop through operands. After
      --  this loop is complete, always contains the last operand (which is not
      --  the same as Operands (NN), since null operands are skipped).

      --  Arrays describing the operands, only the first NN entries of each
      --  array are set (NN < N when we exclude known null operands).

      Is_Fixed_Length : array (1 .. N) of Boolean;
      --  True if length of corresponding operand known at compile time

      Operands : array (1 .. N) of Node_Id;
      --  Set to the corresponding entry in the Opnds list (but note that null
      --  operands are excluded, so not all entries in the list are stored).

      Fixed_Length : array (1 .. N) of Uint;
      --  Set to length of operand. Entries in this array are set only if the
      --  corresponding entry in Is_Fixed_Length is True.

      Opnd_Low_Bound : array (1 .. N) of Node_Id;
      --  Set to lower bound of operand. Either an integer literal in the case
      --  where the bound is known at compile time, else actual lower bound.
      --  The operand low bound is of type Ityp.

      Var_Length : array (1 .. N) of Entity_Id;
      --  Set to an entity of type Natural that contains the length of an
      --  operand whose length is not known at compile time. Entries in this
      --  array are set only if the corresponding entry in Is_Fixed_Length
      --  is False. The entity is of type Artyp.

      Aggr_Length : array (0 .. N) of Node_Id;
      --  The J'th entry in an expression node that represents the total length
      --  of operands 1 through J. It is either an integer literal node, or a
      --  reference to a constant entity with the right value, so it is fine
      --  to just do a Copy_Node to get an appropriate copy. The extra zeroth
      --  entry always is set to zero. The length is of type Artyp.

      Low_Bound : Node_Id;
      --  A tree node representing the low bound of the result (of type Ityp).
      --  This is either an integer literal node, or an identifier reference to
      --  a constant entity initialized to the appropriate value.

      Last_Opnd_Low_Bound : Node_Id := Empty;
      --  A tree node representing the low bound of the last operand. This
      --  need only be set if the result could be null. It is used for the
      --  special case of setting the right low bound for a null result.
      --  This is of type Ityp.

      Last_Opnd_High_Bound : Node_Id := Empty;
      --  A tree node representing the high bound of the last operand. This
      --  need only be set if the result could be null. It is used for the
      --  special case of setting the right high bound for a null result.
      --  This is of type Ityp.

      High_Bound : Node_Id := Empty;
      --  A tree node representing the high bound of the result (of type Ityp)

      Result : Node_Id;
      --  Result of the concatenation (of type Ityp)

      Actions : constant List_Id := New_List;
      --  Collect actions to be inserted

      Known_Non_Null_Operand_Seen : Boolean;
      --  Set True during generation of the assignments of operands into
      --  result once an operand known to be non-null has been seen.

      function Library_Level_Target return Boolean;
      --  Return True if the concatenation is within the expression of the
      --  declaration of a library-level object.

      function Make_Artyp_Literal (Val : Nat) return Node_Id;
      --  This function makes an N_Integer_Literal node that is returned in
      --  analyzed form with the type set to Artyp. Importantly this literal
      --  is not flagged as static, so that if we do computations with it that
      --  result in statically detected out of range conditions, we will not
      --  generate error messages but instead warning messages.

      function To_Artyp (X : Node_Id) return Node_Id;
      --  Given a node of type Ityp, returns the corresponding value of type
      --  Artyp. For non-enumeration types, this is a plain integer conversion.
      --  For enum types, the Pos of the value is returned.

      function To_Ityp (X : Node_Id) return Node_Id;
      --  The inverse function (uses Val in the case of enumeration types)

      --------------------------
      -- Library_Level_Target --
      --------------------------

      function Library_Level_Target return Boolean is
         P : Node_Id := Parent (Cnode);

      begin
         while Present (P) loop
            if Nkind (P) = N_Object_Declaration then
               return Is_Library_Level_Entity (Defining_Identifier (P));

            --  Prevent the search from going too far

            elsif Is_Body_Or_Package_Declaration (P) then
               return False;
            end if;

            P := Parent (P);
         end loop;

         return False;
      end Library_Level_Target;

      ------------------------
      -- Make_Artyp_Literal --
      ------------------------

      function Make_Artyp_Literal (Val : Nat) return Node_Id is
         Result : constant Node_Id := Make_Integer_Literal (Loc, Val);
      begin
         Set_Etype (Result, Artyp);
         Set_Analyzed (Result, True);
         Set_Is_Static_Expression (Result, False);
         return Result;
      end Make_Artyp_Literal;

      --------------
      -- To_Artyp --
      --------------

      function To_Artyp (X : Node_Id) return Node_Id is
      begin
         if Ityp = Base_Type (Artyp) then
            return X;

         elsif Is_Enumeration_Type (Ityp) then
            return
              Make_Attribute_Reference (Loc,
                Prefix         => New_Occurrence_Of (Ityp, Loc),
                Attribute_Name => Name_Pos,
                Expressions    => New_List (X));

         else
            return Convert_To (Artyp, X);
         end if;
      end To_Artyp;

      -------------
      -- To_Ityp --
      -------------

      function To_Ityp (X : Node_Id) return Node_Id is
      begin
         if Is_Enumeration_Type (Ityp) then
            return
              Make_Attribute_Reference (Loc,
                Prefix         => New_Occurrence_Of (Ityp, Loc),
                Attribute_Name => Name_Val,
                Expressions    => New_List (X));

         --  Case where we will do a type conversion

         else
            if Ityp = Base_Type (Artyp) then
               return X;
            else
               return Convert_To (Ityp, X);
            end if;
         end if;
      end To_Ityp;

      --  Local Declarations

      Opnd_Typ : Entity_Id;
      Ent      : Entity_Id;
      Len      : Uint;
      J        : Nat;
      Clen     : Node_Id;
      Set      : Boolean;

   --  Start of processing for Expand_Concatenate

   begin
      --  Choose an appropriate computational type

      --  We will be doing calculations of lengths and bounds in this routine
      --  and computing one from the other in some cases, e.g. getting the high
      --  bound by adding the length-1 to the low bound.

      --  We can't just use the index type, or even its base type for this
      --  purpose for two reasons. First it might be an enumeration type which
      --  is not suitable for computations of any kind, and second it may
      --  simply not have enough range. For example if the index type is
      --  -128..+127 then lengths can be up to 256, which is out of range of
      --  the type.

      --  For enumeration types, we can simply use Standard_Integer, this is
      --  sufficient since the actual number of enumeration literals cannot
      --  possibly exceed the range of integer (remember we will be doing the
      --  arithmetic with POS values, not representation values).

      if Is_Enumeration_Type (Ityp) then
         Artyp := Standard_Integer;

      --  If index type is Positive, we use the standard unsigned type, to give
      --  more room on the top of the range, obviating the need for an overflow
      --  check when creating the upper bound. This is needed to avoid junk
      --  overflow checks in the common case of String types.

      --  ??? Disabled for now

      --  elsif Istyp = Standard_Positive then
      --     Artyp := Standard_Unsigned;

      --  For modular types, we use a 32-bit modular type for types whose size
      --  is in the range 1-31 bits. For 32-bit unsigned types, we use the
      --  identity type, and for larger unsigned types we use 64-bits.

      elsif Is_Modular_Integer_Type (Ityp) then
         if RM_Size (Ityp) < RM_Size (Standard_Unsigned) then
            Artyp := Standard_Unsigned;
         elsif RM_Size (Ityp) = RM_Size (Standard_Unsigned) then
            Artyp := Ityp;
         else
            Artyp := RTE (RE_Long_Long_Unsigned);
         end if;

      --  Similar treatment for signed types

      else
         if RM_Size (Ityp) < RM_Size (Standard_Integer) then
            Artyp := Standard_Integer;
         elsif RM_Size (Ityp) = RM_Size (Standard_Integer) then
            Artyp := Ityp;
         else
            Artyp := Standard_Long_Long_Integer;
         end if;
      end if;

      --  Supply dummy entry at start of length array

      Aggr_Length (0) := Make_Artyp_Literal (0);

      --  Go through operands setting up the above arrays

      J := 1;
      while J <= N loop
         Opnd := Remove_Head (Opnds);
         Opnd_Typ := Etype (Opnd);

         --  The parent got messed up when we put the operands in a list,
         --  so now put back the proper parent for the saved operand, that
         --  is to say the concatenation node, to make sure that each operand
         --  is seen as a subexpression, e.g. if actions must be inserted.

         Set_Parent (Opnd, Cnode);

         --  Set will be True when we have setup one entry in the array

         Set := False;

         --  Singleton element (or character literal) case

         if Base_Type (Opnd_Typ) = Ctyp then
            NN := NN + 1;
            Operands (NN) := Opnd;
            Is_Fixed_Length (NN) := True;
            Fixed_Length (NN) := Uint_1;
            Result_May_Be_Null := False;

            --  Set low bound of operand (no need to set Last_Opnd_High_Bound
            --  since we know that the result cannot be null).

            Opnd_Low_Bound (NN) :=
              Make_Attribute_Reference (Loc,
                Prefix         => New_Occurrence_Of (Istyp, Loc),
                Attribute_Name => Name_First);

            Set := True;

         --  String literal case (can only occur for strings of course)

         elsif Nkind (Opnd) = N_String_Literal then
            Len := String_Literal_Length (Opnd_Typ);

            if Len /= 0 then
               Result_May_Be_Null := False;
            end if;

            --  Capture last operand low and high bound if result could be null

            if J = N and then Result_May_Be_Null then
               Last_Opnd_Low_Bound :=
                 New_Copy_Tree (String_Literal_Low_Bound (Opnd_Typ));

               Last_Opnd_High_Bound :=
                 Make_Op_Subtract (Loc,
                   Left_Opnd  =>
                     New_Copy_Tree (String_Literal_Low_Bound (Opnd_Typ)),
                   Right_Opnd => Make_Integer_Literal (Loc, 1));
            end if;

            --  Skip null string literal

            if J < N and then Len = 0 then
               goto Continue;
            end if;

            NN := NN + 1;
            Operands (NN) := Opnd;
            Is_Fixed_Length (NN) := True;

            --  Set length and bounds

            Fixed_Length (NN) := Len;

            Opnd_Low_Bound (NN) :=
              New_Copy_Tree (String_Literal_Low_Bound (Opnd_Typ));

            Set := True;

         --  All other cases

         else
            --  Check constrained case with known bounds

            if Is_Constrained (Opnd_Typ) then
               declare
                  Index    : constant Node_Id   := First_Index (Opnd_Typ);
                  Indx_Typ : constant Entity_Id := Etype (Index);
                  Lo       : constant Node_Id   := Type_Low_Bound  (Indx_Typ);
                  Hi       : constant Node_Id   := Type_High_Bound (Indx_Typ);

               begin
                  --  Fixed length constrained array type with known at compile
                  --  time bounds is last case of fixed length operand.

                  if Compile_Time_Known_Value (Lo)
                       and then
                     Compile_Time_Known_Value (Hi)
                  then
                     declare
                        Loval : constant Uint := Expr_Value (Lo);
                        Hival : constant Uint := Expr_Value (Hi);
                        Len   : constant Uint :=
                                  UI_Max (Hival - Loval + 1, Uint_0);

                     begin
                        if Len > 0 then
                           Result_May_Be_Null := False;
                        end if;

                        --  Capture last operand bounds if result could be null

                        if J = N and then Result_May_Be_Null then
                           Last_Opnd_Low_Bound :=
                             Convert_To (Ityp,
                               Make_Integer_Literal (Loc, Expr_Value (Lo)));

                           Last_Opnd_High_Bound :=
                             Convert_To (Ityp,
                               Make_Integer_Literal (Loc, Expr_Value (Hi)));
                        end if;

                        --  Exclude null length case unless last operand

                        if J < N and then Len = 0 then
                           goto Continue;
                        end if;

                        NN := NN + 1;
                        Operands (NN) := Opnd;
                        Is_Fixed_Length (NN) := True;
                        Fixed_Length (NN)    := Len;

                        Opnd_Low_Bound (NN) :=
                          To_Ityp
                            (Make_Integer_Literal (Loc, Expr_Value (Lo)));
                        Set := True;
                     end;
                  end if;
               end;
            end if;

            --  All cases where the length is not known at compile time, or the
            --  special case of an operand which is known to be null but has a
            --  lower bound other than 1 or is other than a string type.

            if not Set then
               NN := NN + 1;

               --  Capture operand bounds

               Opnd_Low_Bound (NN) :=
                 Make_Attribute_Reference (Loc,
                   Prefix         =>
                     Duplicate_Subexpr (Opnd, Name_Req => True),
                   Attribute_Name => Name_First);

               --  Capture last operand bounds if result could be null

               if J = N and Result_May_Be_Null then
                  Last_Opnd_Low_Bound :=
                    Convert_To (Ityp,
                      Make_Attribute_Reference (Loc,
                        Prefix         =>
                          Duplicate_Subexpr (Opnd, Name_Req => True),
                        Attribute_Name => Name_First));

                  Last_Opnd_High_Bound :=
                    Convert_To (Ityp,
                      Make_Attribute_Reference (Loc,
                        Prefix         =>
                          Duplicate_Subexpr (Opnd, Name_Req => True),
                        Attribute_Name => Name_Last));
               end if;

               --  Capture length of operand in entity

               Operands (NN) := Opnd;
               Is_Fixed_Length (NN) := False;

               Var_Length (NN) := Make_Temporary (Loc, 'L');

               Append_To (Actions,
                 Make_Object_Declaration (Loc,
                   Defining_Identifier => Var_Length (NN),
                   Constant_Present    => True,
                   Object_Definition   => New_Occurrence_Of (Artyp, Loc),
                   Expression          =>
                     Make_Attribute_Reference (Loc,
                       Prefix         =>
                         Duplicate_Subexpr (Opnd, Name_Req => True),
                       Attribute_Name => Name_Length)));
            end if;
         end if;

         --  Set next entry in aggregate length array

         --  For first entry, make either integer literal for fixed length
         --  or a reference to the saved length for variable length.

         if NN = 1 then
            if Is_Fixed_Length (1) then
               Aggr_Length (1) := Make_Integer_Literal (Loc, Fixed_Length (1));
            else
               Aggr_Length (1) := New_Occurrence_Of (Var_Length (1), Loc);
            end if;

         --  If entry is fixed length and only fixed lengths so far, make
         --  appropriate new integer literal adding new length.

         elsif Is_Fixed_Length (NN)
           and then Nkind (Aggr_Length (NN - 1)) = N_Integer_Literal
         then
            Aggr_Length (NN) :=
              Make_Integer_Literal (Loc,
                Intval => Fixed_Length (NN) + Intval (Aggr_Length (NN - 1)));

         --  All other cases, construct an addition node for the length and
         --  create an entity initialized to this length.

         else
            Ent := Make_Temporary (Loc, 'L');

            if Is_Fixed_Length (NN) then
               Clen := Make_Integer_Literal (Loc, Fixed_Length (NN));
            else
               Clen := New_Occurrence_Of (Var_Length (NN), Loc);
            end if;

            Append_To (Actions,
              Make_Object_Declaration (Loc,
                Defining_Identifier => Ent,
                Constant_Present    => True,
                Object_Definition   => New_Occurrence_Of (Artyp, Loc),
                Expression          =>
                  Make_Op_Add (Loc,
                    Left_Opnd  => New_Copy_Tree (Aggr_Length (NN - 1)),
                    Right_Opnd => Clen)));

            Aggr_Length (NN) := Make_Identifier (Loc, Chars => Chars (Ent));
         end if;

      <<Continue>>
         J := J + 1;
      end loop;

      --  If we have only skipped null operands, return the last operand

      if NN = 0 then
         Result := Opnd;
         goto Done;
      end if;

      --  If we have only one non-null operand, return it and we are done.
      --  There is one case in which this cannot be done, and that is when
      --  the sole operand is of the element type, in which case it must be
      --  converted to an array, and the easiest way of doing that is to go
      --  through the normal general circuit.

      if NN = 1 and then Base_Type (Etype (Operands (1))) /= Ctyp then
         Result := Operands (1);
         goto Done;
      end if;

      --  Cases where we have a real concatenation

      --  Next step is to find the low bound for the result array that we
      --  will allocate. The rules for this are in (RM 4.5.6(5-7)).

      --  If the ultimate ancestor of the index subtype is a constrained array
      --  definition, then the lower bound is that of the index subtype as
      --  specified by (RM 4.5.3(6)).

      --  The right test here is to go to the root type, and then the ultimate
      --  ancestor is the first subtype of this root type.

      if Is_Constrained (First_Subtype (Root_Type (Atyp))) then
         Low_Bound :=
           Make_Attribute_Reference (Loc,
             Prefix         =>
               New_Occurrence_Of (First_Subtype (Root_Type (Atyp)), Loc),
             Attribute_Name => Name_First);

      --  If the first operand in the list has known length we know that
      --  the lower bound of the result is the lower bound of this operand.

      elsif Is_Fixed_Length (1) then
         Low_Bound := Opnd_Low_Bound (1);

      --  OK, we don't know the lower bound, we have to build a horrible
      --  if expression node of the form

      --     if Cond1'Length /= 0 then
      --        Opnd1 low bound
      --     else
      --        if Opnd2'Length /= 0 then
      --          Opnd2 low bound
      --        else
      --           ...

      --  The nesting ends either when we hit an operand whose length is known
      --  at compile time, or on reaching the last operand, whose low bound we
      --  take unconditionally whether or not it is null. It's easiest to do
      --  this with a recursive procedure:

      else
         declare
            function Get_Known_Bound (J : Nat) return Node_Id;
            --  Returns the lower bound determined by operands J .. NN

            ---------------------
            -- Get_Known_Bound --
            ---------------------

            function Get_Known_Bound (J : Nat) return Node_Id is
            begin
               if Is_Fixed_Length (J) or else J = NN then
                  return New_Copy_Tree (Opnd_Low_Bound (J));

               else
                  return
                    Make_If_Expression (Loc,
                      Expressions => New_List (

                        Make_Op_Ne (Loc,
                          Left_Opnd  =>
                            New_Occurrence_Of (Var_Length (J), Loc),
                          Right_Opnd =>
                            Make_Integer_Literal (Loc, 0)),

                        New_Copy_Tree (Opnd_Low_Bound (J)),
                        Get_Known_Bound (J + 1)));
               end if;
            end Get_Known_Bound;

         begin
            Ent := Make_Temporary (Loc, 'L');

            Append_To (Actions,
              Make_Object_Declaration (Loc,
                Defining_Identifier => Ent,
                Constant_Present    => True,
                Object_Definition   => New_Occurrence_Of (Ityp, Loc),
                Expression          => Get_Known_Bound (1)));

            Low_Bound := New_Occurrence_Of (Ent, Loc);
         end;
      end if;

      --  Now we can safely compute the upper bound, normally
      --  Low_Bound + Length - 1.

      High_Bound :=
        To_Ityp
          (Make_Op_Add (Loc,
             Left_Opnd  => To_Artyp (New_Copy_Tree (Low_Bound)),
             Right_Opnd =>
               Make_Op_Subtract (Loc,
                 Left_Opnd  => New_Copy_Tree (Aggr_Length (NN)),
                 Right_Opnd => Make_Artyp_Literal (1))));

      --  Note that calculation of the high bound may cause overflow in some
      --  very weird cases, so in the general case we need an overflow check on
      --  the high bound. We can avoid this for the common case of string types
      --  and other types whose index is Positive, since we chose a wider range
      --  for the arithmetic type. If checks are suppressed we do not set the
      --  flag, and possibly superfluous warnings will be omitted.

      if Istyp /= Standard_Positive
        and then not Overflow_Checks_Suppressed (Istyp)
      then
         Activate_Overflow_Check (High_Bound);
      end if;

      --  Handle the exceptional case where the result is null, in which case
      --  case the bounds come from the last operand (so that we get the proper
      --  bounds if the last operand is super-flat).

      if Result_May_Be_Null then
         Low_Bound :=
           Make_If_Expression (Loc,
             Expressions => New_List (
               Make_Op_Eq (Loc,
                 Left_Opnd  => New_Copy_Tree (Aggr_Length (NN)),
                 Right_Opnd => Make_Artyp_Literal (0)),
               Last_Opnd_Low_Bound,
               Low_Bound));

         High_Bound :=
           Make_If_Expression (Loc,
             Expressions => New_List (
               Make_Op_Eq (Loc,
                 Left_Opnd  => New_Copy_Tree (Aggr_Length (NN)),
                 Right_Opnd => Make_Artyp_Literal (0)),
               Last_Opnd_High_Bound,
               High_Bound));
      end if;

      --  Here is where we insert the saved up actions

      Insert_Actions (Cnode, Actions, Suppress => All_Checks);

      --  Now we construct an array object with appropriate bounds. We mark
      --  the target as internal to prevent useless initialization when
      --  Initialize_Scalars is enabled. Also since this is the actual result
      --  entity, we make sure we have debug information for the result.

      Ent := Make_Temporary (Loc, 'S');
      Set_Is_Internal       (Ent);
      Set_Debug_Info_Needed (Ent);

      --  If the bound is statically known to be out of range, we do not want
      --  to abort, we want a warning and a runtime constraint error. Note that
      --  we have arranged that the result will not be treated as a static
      --  constant, so we won't get an illegality during this insertion.

      Insert_Action (Cnode,
        Make_Object_Declaration (Loc,
          Defining_Identifier => Ent,
          Object_Definition   =>
            Make_Subtype_Indication (Loc,
              Subtype_Mark => New_Occurrence_Of (Atyp, Loc),
              Constraint   =>
                Make_Index_Or_Discriminant_Constraint (Loc,
                  Constraints => New_List (
                    Make_Range (Loc,
                      Low_Bound  => Low_Bound,
                      High_Bound => High_Bound))))),
        Suppress => All_Checks);

      --  If the result of the concatenation appears as the initializing
      --  expression of an object declaration, we can just rename the
      --  result, rather than copying it.

      Set_OK_To_Rename (Ent);

      --  Catch the static out of range case now

      if Raises_Constraint_Error (High_Bound) then
         raise Concatenation_Error;
      end if;

      --  Now we will generate the assignments to do the actual concatenation

      --  There is one case in which we will not do this, namely when all the
      --  following conditions are met:

      --    The result type is Standard.String

      --    There are nine or fewer retained (non-null) operands

      --    The optimization level is -O0 or the debug flag gnatd.C is set,
      --    and the debug flag gnatd.c is not set.

      --    The corresponding System.Concat_n.Str_Concat_n routine is
      --    available in the run time.

      --  If all these conditions are met then we generate a call to the
      --  relevant concatenation routine. The purpose of this is to avoid
      --  undesirable code bloat at -O0.

      --  If the concatenation is within the declaration of a library-level
      --  object, we call the built-in concatenation routines to prevent code
      --  bloat, regardless of the optimization level. This is space efficient
      --  and prevents linking problems when units are compiled with different
      --  optimization levels.

      if Atyp = Standard_String
        and then NN in 2 .. 9
        and then (((Optimization_Level = 0 or else Debug_Flag_Dot_CC)
                     and then not Debug_Flag_Dot_C)
                  or else Library_Level_Target)
      then
         declare
            RR : constant array (Nat range 2 .. 9) of RE_Id :=
                   (RE_Str_Concat_2,
                    RE_Str_Concat_3,
                    RE_Str_Concat_4,
                    RE_Str_Concat_5,
                    RE_Str_Concat_6,
                    RE_Str_Concat_7,
                    RE_Str_Concat_8,
                    RE_Str_Concat_9);

         begin
            if RTE_Available (RR (NN)) then
               declare
                  Opnds : constant List_Id :=
                            New_List (New_Occurrence_Of (Ent, Loc));

               begin
                  for J in 1 .. NN loop
                     if Is_List_Member (Operands (J)) then
                        Remove (Operands (J));
                     end if;

                     if Base_Type (Etype (Operands (J))) = Ctyp then
                        Append_To (Opnds,
                          Make_Aggregate (Loc,
                            Component_Associations => New_List (
                              Make_Component_Association (Loc,
                                Choices => New_List (
                                  Make_Integer_Literal (Loc, 1)),
                                Expression => Operands (J)))));

                     else
                        Append_To (Opnds, Operands (J));
                     end if;
                  end loop;

                  Insert_Action (Cnode,
                    Make_Procedure_Call_Statement (Loc,
                      Name => New_Occurrence_Of (RTE (RR (NN)), Loc),
                      Parameter_Associations => Opnds));

                  Result := New_Occurrence_Of (Ent, Loc);
                  goto Done;
               end;
            end if;
         end;
      end if;

      --  Not special case so generate the assignments

      Known_Non_Null_Operand_Seen := False;

      for J in 1 .. NN loop
         declare
            Lo : constant Node_Id :=
                   Make_Op_Add (Loc,
                     Left_Opnd  => To_Artyp (New_Copy_Tree (Low_Bound)),
                     Right_Opnd => Aggr_Length (J - 1));

            Hi : constant Node_Id :=
                   Make_Op_Add (Loc,
                     Left_Opnd  => To_Artyp (New_Copy_Tree (Low_Bound)),
                     Right_Opnd =>
                       Make_Op_Subtract (Loc,
                         Left_Opnd  => Aggr_Length (J),
                         Right_Opnd => Make_Artyp_Literal (1)));

         begin
            --  Singleton case, simple assignment

            if Base_Type (Etype (Operands (J))) = Ctyp then
               Known_Non_Null_Operand_Seen := True;
               Insert_Action (Cnode,
                 Make_Assignment_Statement (Loc,
                   Name       =>
                     Make_Indexed_Component (Loc,
                       Prefix      => New_Occurrence_Of (Ent, Loc),
                       Expressions => New_List (To_Ityp (Lo))),
                   Expression => Operands (J)),
                 Suppress => All_Checks);

            --  Array case, slice assignment, skipped when argument is fixed
            --  length and known to be null.

            elsif (not Is_Fixed_Length (J)) or else (Fixed_Length (J) > 0) then
               declare
                  Assign : Node_Id :=
                             Make_Assignment_Statement (Loc,
                               Name       =>
                                 Make_Slice (Loc,
                                   Prefix         =>
                                     New_Occurrence_Of (Ent, Loc),
                                   Discrete_Range =>
                                     Make_Range (Loc,
                                       Low_Bound  => To_Ityp (Lo),
                                       High_Bound => To_Ityp (Hi))),
                               Expression => Operands (J));
               begin
                  if Is_Fixed_Length (J) then
                     Known_Non_Null_Operand_Seen := True;

                  elsif not Known_Non_Null_Operand_Seen then

                     --  Here if operand length is not statically known and no
                     --  operand known to be non-null has been processed yet.
                     --  If operand length is 0, we do not need to perform the
                     --  assignment, and we must avoid the evaluation of the
                     --  high bound of the slice, since it may underflow if the
                     --  low bound is Ityp'First.

                     Assign :=
                       Make_Implicit_If_Statement (Cnode,
                         Condition       =>
                           Make_Op_Ne (Loc,
                             Left_Opnd  =>
                               New_Occurrence_Of (Var_Length (J), Loc),
                             Right_Opnd => Make_Integer_Literal (Loc, 0)),
                         Then_Statements => New_List (Assign));
                  end if;

                  Insert_Action (Cnode, Assign, Suppress => All_Checks);
               end;
            end if;
         end;
      end loop;

      --  Finally we build the result, which is a reference to the array object

      Result := New_Occurrence_Of (Ent, Loc);

   <<Done>>
      Rewrite (Cnode, Result);
      Analyze_And_Resolve (Cnode, Atyp);

   exception
      when Concatenation_Error =>

         --  Kill warning generated for the declaration of the static out of
         --  range high bound, and instead generate a Constraint_Error with
         --  an appropriate specific message.

         Kill_Dead_Code (Declaration_Node (Entity (High_Bound)));
         Apply_Compile_Time_Constraint_Error
           (N      => Cnode,
            Msg    => "concatenation result upper bound out of range??",
            Reason => CE_Range_Check_Failed);
   end Expand_Concatenate;

   ---------------------------------------------------
   -- Expand_Membership_Minimize_Eliminate_Overflow --
   ---------------------------------------------------

   procedure Expand_Membership_Minimize_Eliminate_Overflow (N : Node_Id) is
      pragma Assert (Nkind (N) = N_In);
      --  Despite the name, this routine applies only to N_In, not to
      --  N_Not_In. The latter is always rewritten as not (X in Y).

      Result_Type : constant Entity_Id := Etype (N);
      --  Capture result type, may be a derived boolean type

      Loc : constant Source_Ptr := Sloc (N);
      Lop : constant Node_Id    := Left_Opnd (N);
      Rop : constant Node_Id    := Right_Opnd (N);

      --  Note: there are many referencs to Etype (Lop) and Etype (Rop). It
      --  is thus tempting to capture these values, but due to the rewrites
      --  that occur as a result of overflow checking, these values change
      --  as we go along, and it is safe just to always use Etype explicitly.

      Restype : constant Entity_Id := Etype (N);
      --  Save result type

      Lo, Hi : Uint;
      --  Bounds in Minimize calls, not used currently

      LLIB : constant Entity_Id := Base_Type (Standard_Long_Long_Integer);
      --  Entity for Long_Long_Integer'Base (Standard should export this???)

   begin
      Minimize_Eliminate_Overflows (Lop, Lo, Hi, Top_Level => False);

      --  If right operand is a subtype name, and the subtype name has no
      --  predicate, then we can just replace the right operand with an
      --  explicit range T'First .. T'Last, and use the explicit range code.

      if Nkind (Rop) /= N_Range
        and then No (Predicate_Function (Etype (Rop)))
      then
         declare
            Rtyp : constant Entity_Id := Etype (Rop);
         begin
            Rewrite (Rop,
              Make_Range (Loc,
                Low_Bound  =>
                  Make_Attribute_Reference (Loc,
                    Attribute_Name => Name_First,
                    Prefix         => New_Occurrence_Of (Rtyp, Loc)),
                High_Bound =>
                  Make_Attribute_Reference (Loc,
                    Attribute_Name => Name_Last,
                    Prefix         => New_Occurrence_Of (Rtyp, Loc))));
            Analyze_And_Resolve (Rop, Rtyp, Suppress => All_Checks);
         end;
      end if;

      --  Here for the explicit range case. Note that the bounds of the range
      --  have not been processed for minimized or eliminated checks.

      if Nkind (Rop) = N_Range then
         Minimize_Eliminate_Overflows
           (Low_Bound (Rop), Lo, Hi, Top_Level => False);
         Minimize_Eliminate_Overflows
           (High_Bound (Rop), Lo, Hi, Top_Level => False);

         --  We have A in B .. C, treated as  A >= B and then A <= C

         --  Bignum case

         if Is_RTE (Etype (Lop), RE_Bignum)
           or else Is_RTE (Etype (Low_Bound (Rop)), RE_Bignum)
           or else Is_RTE (Etype (High_Bound (Rop)), RE_Bignum)
         then
            declare
               Blk    : constant Node_Id   := Make_Bignum_Block (Loc);
               Bnn    : constant Entity_Id := Make_Temporary (Loc, 'B', N);
               L      : constant Entity_Id :=
                          Make_Defining_Identifier (Loc, Name_uL);
               Lopnd  : constant Node_Id   := Convert_To_Bignum (Lop);
               Lbound : constant Node_Id   :=
                          Convert_To_Bignum (Low_Bound (Rop));
               Hbound : constant Node_Id   :=
                          Convert_To_Bignum (High_Bound (Rop));

            --  Now we rewrite the membership test node to look like

            --    do
            --       Bnn : Result_Type;
            --       declare
            --          M : Mark_Id := SS_Mark;
            --          L : Bignum  := Lopnd;
            --       begin
            --          Bnn := Big_GE (L, Lbound) and then Big_LE (L, Hbound)
            --          SS_Release (M);
            --       end;
            --    in
            --       Bnn
            --    end

            begin
               --  Insert declaration of L into declarations of bignum block

               Insert_After
                 (Last (Declarations (Blk)),
                  Make_Object_Declaration (Loc,
                    Defining_Identifier => L,
                    Object_Definition   =>
                      New_Occurrence_Of (RTE (RE_Bignum), Loc),
                    Expression          => Lopnd));

               --  Insert assignment to Bnn into expressions of bignum block

               Insert_Before
                 (First (Statements (Handled_Statement_Sequence (Blk))),
                  Make_Assignment_Statement (Loc,
                    Name       => New_Occurrence_Of (Bnn, Loc),
                    Expression =>
                      Make_And_Then (Loc,
                        Left_Opnd  =>
                          Make_Function_Call (Loc,
                            Name                   =>
                              New_Occurrence_Of (RTE (RE_Big_GE), Loc),
                            Parameter_Associations => New_List (
                              New_Occurrence_Of (L, Loc),
                              Lbound)),

                        Right_Opnd =>
                          Make_Function_Call (Loc,
                            Name                   =>
                              New_Occurrence_Of (RTE (RE_Big_LE), Loc),
                            Parameter_Associations => New_List (
                              New_Occurrence_Of (L, Loc),
                              Hbound)))));

               --  Now rewrite the node

               Rewrite (N,
                 Make_Expression_With_Actions (Loc,
                   Actions    => New_List (
                     Make_Object_Declaration (Loc,
                       Defining_Identifier => Bnn,
                       Object_Definition   =>
                         New_Occurrence_Of (Result_Type, Loc)),
                     Blk),
                   Expression => New_Occurrence_Of (Bnn, Loc)));
               Analyze_And_Resolve (N, Result_Type);
               return;
            end;

         --  Here if no bignums around

         else
            --  Case where types are all the same

            if Base_Type (Etype (Lop)) = Base_Type (Etype (Low_Bound (Rop)))
                 and then
               Base_Type (Etype (Lop)) = Base_Type (Etype (High_Bound (Rop)))
            then
               null;

            --  If types are not all the same, it means that we have rewritten
            --  at least one of them to be of type Long_Long_Integer, and we
            --  will convert the other operands to Long_Long_Integer.

            else
               Convert_To_And_Rewrite (LLIB, Lop);
               Set_Analyzed (Lop, False);
               Analyze_And_Resolve (Lop, LLIB);

               --  For the right operand, avoid unnecessary recursion into
               --  this routine, we know that overflow is not possible.

               Convert_To_And_Rewrite (LLIB, Low_Bound (Rop));
               Convert_To_And_Rewrite (LLIB, High_Bound (Rop));
               Set_Analyzed (Rop, False);
               Analyze_And_Resolve (Rop, LLIB, Suppress => Overflow_Check);
            end if;

            --  Now the three operands are of the same signed integer type,
            --  so we can use the normal expansion routine for membership,
            --  setting the flag to prevent recursion into this procedure.

            Set_No_Minimize_Eliminate (N);
            Expand_N_In (N);
         end if;

      --  Right operand is a subtype name and the subtype has a predicate. We
      --  have to make sure the predicate is checked, and for that we need to
      --  use the standard N_In circuitry with appropriate types.

      else
         pragma Assert (Present (Predicate_Function (Etype (Rop))));

         --  If types are "right", just call Expand_N_In preventing recursion

         if Base_Type (Etype (Lop)) = Base_Type (Etype (Rop)) then
            Set_No_Minimize_Eliminate (N);
            Expand_N_In (N);

         --  Bignum case

         elsif Is_RTE (Etype (Lop), RE_Bignum) then

            --  For X in T, we want to rewrite our node as

            --    do
            --       Bnn : Result_Type;

            --       declare
            --          M   : Mark_Id := SS_Mark;
            --          Lnn : Long_Long_Integer'Base
            --          Nnn : Bignum;

            --       begin
            --         Nnn := X;

            --         if not Bignum_In_LLI_Range (Nnn) then
            --            Bnn := False;
            --         else
            --            Lnn := From_Bignum (Nnn);
            --            Bnn :=
            --              Lnn in LLIB (T'Base'First) .. LLIB (T'Base'Last)
            --                and then T'Base (Lnn) in T;
            --         end if;

            --         SS_Release (M);
            --       end
            --   in
            --       Bnn
            --   end

            --  A bit gruesome, but there doesn't seem to be a simpler way

            declare
               Blk : constant Node_Id   := Make_Bignum_Block (Loc);
               Bnn : constant Entity_Id := Make_Temporary (Loc, 'B', N);
               Lnn : constant Entity_Id := Make_Temporary (Loc, 'L', N);
               Nnn : constant Entity_Id := Make_Temporary (Loc, 'N', N);
               T   : constant Entity_Id := Etype (Rop);
               TB  : constant Entity_Id := Base_Type (T);
               Nin : Node_Id;

            begin
               --  Mark the last membership operation to prevent recursion

               Nin :=
                 Make_In (Loc,
                   Left_Opnd  => Convert_To (TB, New_Occurrence_Of (Lnn, Loc)),
                   Right_Opnd => New_Occurrence_Of (T, Loc));
               Set_No_Minimize_Eliminate (Nin);

               --  Now decorate the block

               Insert_After
                 (Last (Declarations (Blk)),
                  Make_Object_Declaration (Loc,
                    Defining_Identifier => Lnn,
                    Object_Definition   => New_Occurrence_Of (LLIB, Loc)));

               Insert_After
                 (Last (Declarations (Blk)),
                  Make_Object_Declaration (Loc,
                    Defining_Identifier => Nnn,
                    Object_Definition   =>
                      New_Occurrence_Of (RTE (RE_Bignum), Loc)));

               Insert_List_Before
                 (First (Statements (Handled_Statement_Sequence (Blk))),
                  New_List (
                    Make_Assignment_Statement (Loc,
                      Name       => New_Occurrence_Of (Nnn, Loc),
                      Expression => Relocate_Node (Lop)),

                    Make_Implicit_If_Statement (N,
                      Condition =>
                        Make_Op_Not (Loc,
                          Right_Opnd =>
                            Make_Function_Call (Loc,
                              Name                   =>
                                New_Occurrence_Of
                                  (RTE (RE_Bignum_In_LLI_Range), Loc),
                              Parameter_Associations => New_List (
                                New_Occurrence_Of (Nnn, Loc)))),

                      Then_Statements => New_List (
                        Make_Assignment_Statement (Loc,
                          Name       => New_Occurrence_Of (Bnn, Loc),
                          Expression =>
                            New_Occurrence_Of (Standard_False, Loc))),

                      Else_Statements => New_List (
                        Make_Assignment_Statement (Loc,
                          Name => New_Occurrence_Of (Lnn, Loc),
                          Expression =>
                            Make_Function_Call (Loc,
                              Name                   =>
                                New_Occurrence_Of (RTE (RE_From_Bignum), Loc),
                              Parameter_Associations => New_List (
                                  New_Occurrence_Of (Nnn, Loc)))),

                        Make_Assignment_Statement (Loc,
                          Name       => New_Occurrence_Of (Bnn, Loc),
                          Expression =>
                            Make_And_Then (Loc,
                              Left_Opnd  =>
                                Make_In (Loc,
                                  Left_Opnd  => New_Occurrence_Of (Lnn, Loc),
                                  Right_Opnd =>
                                    Make_Range (Loc,
                                      Low_Bound  =>
                                        Convert_To (LLIB,
                                          Make_Attribute_Reference (Loc,
                                            Attribute_Name => Name_First,
                                            Prefix         =>
                                              New_Occurrence_Of (TB, Loc))),

                                      High_Bound =>
                                        Convert_To (LLIB,
                                          Make_Attribute_Reference (Loc,
                                            Attribute_Name => Name_Last,
                                            Prefix         =>
                                              New_Occurrence_Of (TB, Loc))))),

                              Right_Opnd => Nin))))));

               --  Now we can do the rewrite

               Rewrite (N,
                 Make_Expression_With_Actions (Loc,
                   Actions    => New_List (
                     Make_Object_Declaration (Loc,
                       Defining_Identifier => Bnn,
                       Object_Definition   =>
                         New_Occurrence_Of (Result_Type, Loc)),
                     Blk),
                   Expression => New_Occurrence_Of (Bnn, Loc)));
               Analyze_And_Resolve (N, Result_Type);
               return;
            end;

         --  Not bignum case, but types don't match (this means we rewrote the
         --  left operand to be Long_Long_Integer).

         else
            pragma Assert (Base_Type (Etype (Lop)) = LLIB);

            --  We rewrite the membership test as (where T is the type with
            --  the predicate, i.e. the type of the right operand)

            --    Lop in LLIB (T'Base'First) .. LLIB (T'Base'Last)
            --      and then T'Base (Lop) in T

            declare
               T   : constant Entity_Id := Etype (Rop);
               TB  : constant Entity_Id := Base_Type (T);
               Nin : Node_Id;

            begin
               --  The last membership test is marked to prevent recursion

               Nin :=
                 Make_In (Loc,
                   Left_Opnd  => Convert_To (TB, Duplicate_Subexpr (Lop)),
                   Right_Opnd => New_Occurrence_Of (T, Loc));
               Set_No_Minimize_Eliminate (Nin);

               --  Now do the rewrite

               Rewrite (N,
                 Make_And_Then (Loc,
                   Left_Opnd  =>
                     Make_In (Loc,
                       Left_Opnd  => Lop,
                       Right_Opnd =>
                         Make_Range (Loc,
                           Low_Bound  =>
                             Convert_To (LLIB,
                               Make_Attribute_Reference (Loc,
                                 Attribute_Name => Name_First,
                                 Prefix         =>
                                   New_Occurrence_Of (TB, Loc))),
                           High_Bound =>
                             Convert_To (LLIB,
                               Make_Attribute_Reference (Loc,
                                 Attribute_Name => Name_Last,
                                 Prefix         =>
                                   New_Occurrence_Of (TB, Loc))))),
                   Right_Opnd => Nin));
               Set_Analyzed (N, False);
               Analyze_And_Resolve (N, Restype);
            end;
         end if;
      end if;
   end Expand_Membership_Minimize_Eliminate_Overflow;

   ---------------------------------
   -- Expand_Nonbinary_Modular_Op --
   ---------------------------------

   procedure Expand_Nonbinary_Modular_Op (N : Node_Id) is
      Loc : constant Source_Ptr := Sloc (N);
      Typ : constant Entity_Id  := Etype (N);

      procedure Expand_Modular_Addition;
      --  Expand the modular addition, handling the special case of adding a
      --  constant.

      procedure Expand_Modular_Op;
      --  Compute the general rule: (lhs OP rhs) mod Modulus

      procedure Expand_Modular_Subtraction;
      --  Expand the modular addition, handling the special case of subtracting
      --  a constant.

      -----------------------------
      -- Expand_Modular_Addition --
      -----------------------------

      procedure Expand_Modular_Addition is
      begin
         --  If this is not the addition of a constant then compute it using
         --  the general rule: (lhs + rhs) mod Modulus

         if Nkind (Right_Opnd (N)) /= N_Integer_Literal then
            Expand_Modular_Op;

         --  If this is an addition of a constant, convert it to a subtraction
         --  plus a conditional expression since we can compute it faster than
         --  computing the modulus.

         --      modMinusRhs = Modulus - rhs
         --      if lhs < modMinusRhs then lhs + rhs
         --                           else lhs - modMinusRhs

         else
            declare
               Mod_Minus_Right : constant Uint :=
                                   Modulus (Typ) - Intval (Right_Opnd (N));

               Exprs     : constant List_Id := New_List;
               Cond_Expr : constant Node_Id := New_Op_Node (N_Op_Lt, Loc);
               Then_Expr : constant Node_Id := New_Op_Node (N_Op_Add, Loc);
               Else_Expr : constant Node_Id := New_Op_Node (N_Op_Subtract,
                                                            Loc);
            begin
               --  To prevent spurious visibility issues, convert all
               --  operands to Standard.Unsigned.

               Set_Left_Opnd (Cond_Expr,
                 Unchecked_Convert_To (Standard_Unsigned,
                   New_Copy_Tree (Left_Opnd (N))));
               Set_Right_Opnd (Cond_Expr,
                 Make_Integer_Literal (Loc, Mod_Minus_Right));
               Append_To (Exprs, Cond_Expr);

               Set_Left_Opnd (Then_Expr,
                 Unchecked_Convert_To (Standard_Unsigned,
                   New_Copy_Tree (Left_Opnd (N))));
               Set_Right_Opnd (Then_Expr,
                 Make_Integer_Literal (Loc, Intval (Right_Opnd (N))));
               Append_To (Exprs, Then_Expr);

               Set_Left_Opnd (Else_Expr,
                 Unchecked_Convert_To (Standard_Unsigned,
                   New_Copy_Tree (Left_Opnd (N))));
               Set_Right_Opnd (Else_Expr,
                 Make_Integer_Literal (Loc, Mod_Minus_Right));
               Append_To (Exprs, Else_Expr);

               Rewrite (N,
                 Unchecked_Convert_To (Typ,
                   Make_If_Expression (Loc, Expressions => Exprs)));
            end;
         end if;
      end Expand_Modular_Addition;

      -----------------------
      -- Expand_Modular_Op --
      -----------------------

      procedure Expand_Modular_Op is
         Op_Expr  : constant Node_Id := New_Op_Node (Nkind (N), Loc);
         Mod_Expr : constant Node_Id := New_Op_Node (N_Op_Mod, Loc);

         Target_Type   : Entity_Id;

      begin
         --  Convert nonbinary modular type operands into integer values. Thus
         --  we avoid never-ending loops expanding them, and we also ensure
         --  the back end never receives nonbinary modular type expressions.

         if Nkind_In (Nkind (N), N_Op_And, N_Op_Or, N_Op_Xor) then
            Set_Left_Opnd (Op_Expr,
              Unchecked_Convert_To (Standard_Unsigned,
                New_Copy_Tree (Left_Opnd (N))));
            Set_Right_Opnd (Op_Expr,
              Unchecked_Convert_To (Standard_Unsigned,
                New_Copy_Tree (Right_Opnd (N))));
            Set_Left_Opnd (Mod_Expr,
              Unchecked_Convert_To (Standard_Integer, Op_Expr));

         else
            --  If the modulus of the type is larger than Integer'Last use a
            --  larger type for the operands, to prevent spurious constraint
            --  errors on large legal literals of the type.

            if Modulus (Etype (N)) > UI_From_Int (Int (Integer'Last)) then
               Target_Type := Standard_Long_Integer;
            else
               Target_Type := Standard_Integer;
            end if;

            Set_Left_Opnd (Op_Expr,
              Unchecked_Convert_To (Target_Type,
                New_Copy_Tree (Left_Opnd (N))));
            Set_Right_Opnd (Op_Expr,
              Unchecked_Convert_To (Target_Type,
                New_Copy_Tree (Right_Opnd (N))));

            --  Link this node to the tree to analyze it

            --  If the parent node is an expression with actions we link it to
            --  N since otherwise Force_Evaluation cannot identify if this node
            --  comes from the Expression and rejects generating the temporary.

            if Nkind (Parent (N)) = N_Expression_With_Actions then
               Set_Parent (Op_Expr, N);

            --  Common case

            else
               Set_Parent (Op_Expr, Parent (N));
            end if;

            Analyze (Op_Expr);

            --  Force generating a temporary because in the expansion of this
            --  expression we may generate code that performs this computation
            --  several times.

            Force_Evaluation (Op_Expr, Mode => Strict);

            Set_Left_Opnd (Mod_Expr, Op_Expr);
         end if;

         Set_Right_Opnd (Mod_Expr,
           Make_Integer_Literal (Loc, Modulus (Typ)));

         Rewrite (N,
           Unchecked_Convert_To (Typ, Mod_Expr));
      end Expand_Modular_Op;

      --------------------------------
      -- Expand_Modular_Subtraction --
      --------------------------------

      procedure Expand_Modular_Subtraction is
      begin
         --  If this is not the addition of a constant then compute it using
         --  the general rule: (lhs + rhs) mod Modulus

         if Nkind (Right_Opnd (N)) /= N_Integer_Literal then
            Expand_Modular_Op;

         --  If this is an addition of a constant, convert it to a subtraction
         --  plus a conditional expression since we can compute it faster than
         --  computing the modulus.

         --      modMinusRhs = Modulus - rhs
         --      if lhs < rhs then lhs + modMinusRhs
         --                   else lhs - rhs

         else
            declare
               Mod_Minus_Right : constant Uint :=
                                   Modulus (Typ) - Intval (Right_Opnd (N));

               Exprs     : constant List_Id := New_List;
               Cond_Expr : constant Node_Id := New_Op_Node (N_Op_Lt, Loc);
               Then_Expr : constant Node_Id := New_Op_Node (N_Op_Add, Loc);
               Else_Expr : constant Node_Id := New_Op_Node (N_Op_Subtract,
                                                            Loc);
            begin
               Set_Left_Opnd (Cond_Expr,
                 Unchecked_Convert_To (Standard_Unsigned,
                   New_Copy_Tree (Left_Opnd (N))));
               Set_Right_Opnd (Cond_Expr,
                 Make_Integer_Literal (Loc, Intval (Right_Opnd (N))));
               Append_To (Exprs, Cond_Expr);

               Set_Left_Opnd (Then_Expr,
                 Unchecked_Convert_To (Standard_Unsigned,
                   New_Copy_Tree (Left_Opnd (N))));
               Set_Right_Opnd (Then_Expr,
                 Make_Integer_Literal (Loc, Mod_Minus_Right));
               Append_To (Exprs, Then_Expr);

               Set_Left_Opnd (Else_Expr,
                 Unchecked_Convert_To (Standard_Unsigned,
                   New_Copy_Tree (Left_Opnd (N))));
               Set_Right_Opnd (Else_Expr,
                 Unchecked_Convert_To (Standard_Unsigned,
                   New_Copy_Tree (Right_Opnd (N))));
               Append_To (Exprs, Else_Expr);

               Rewrite (N,
                 Unchecked_Convert_To (Typ,
                   Make_If_Expression (Loc, Expressions => Exprs)));
            end;
         end if;
      end Expand_Modular_Subtraction;

   --  Start of processing for Expand_Nonbinary_Modular_Op

   begin
      --  No action needed if front-end expansion is not required or if we
      --  have a binary modular operand.

      if not Expand_Nonbinary_Modular_Ops
        or else not Non_Binary_Modulus (Typ)
      then
         return;
      end if;

      case Nkind (N) is
         when N_Op_Add =>
            Expand_Modular_Addition;

         when N_Op_Subtract =>
            Expand_Modular_Subtraction;

         when N_Op_Minus =>

            --  Expand -expr into (0 - expr)

            Rewrite (N,
              Make_Op_Subtract (Loc,
                Left_Opnd  => Make_Integer_Literal (Loc, 0),
                Right_Opnd => Right_Opnd (N)));
            Analyze_And_Resolve (N, Typ);

         when others =>
            Expand_Modular_Op;
      end case;

      Analyze_And_Resolve (N, Typ);
   end Expand_Nonbinary_Modular_Op;

   ------------------------
   -- Expand_N_Allocator --
   ------------------------

   procedure Expand_N_Allocator (N : Node_Id) is
      Etyp : constant Entity_Id  := Etype (Expression (N));
      Loc  : constant Source_Ptr := Sloc (N);
      PtrT : constant Entity_Id  := Etype (N);

      procedure Rewrite_Coextension (N : Node_Id);
      --  Static coextensions have the same lifetime as the entity they
      --  constrain. Such occurrences can be rewritten as aliased objects
      --  and their unrestricted access used instead of the coextension.

      function Size_In_Storage_Elements (E : Entity_Id) return Node_Id;
      --  Given a constrained array type E, returns a node representing the
      --  code to compute a close approximation of the size in storage elements
      --  for the given type; for indexes that are modular types we compute
      --  'Last - First (instead of 'Length) because for large arrays computing
      --  'Last -'First + 1 causes overflow. This is done without using the
      --  attribute 'Size_In_Storage_Elements (which malfunctions for large
      --  sizes ???).

      -------------------------
      -- Rewrite_Coextension --
      -------------------------

      procedure Rewrite_Coextension (N : Node_Id) is
         Temp_Id   : constant Node_Id := Make_Temporary (Loc, 'C');
         Temp_Decl : Node_Id;

      begin
         --  Generate:
         --    Cnn : aliased Etyp;

         Temp_Decl :=
           Make_Object_Declaration (Loc,
             Defining_Identifier => Temp_Id,
             Aliased_Present     => True,
             Object_Definition   => New_Occurrence_Of (Etyp, Loc));

         if Nkind (Expression (N)) = N_Qualified_Expression then
            Set_Expression (Temp_Decl, Expression (Expression (N)));
         end if;

         Insert_Action (N, Temp_Decl);
         Rewrite (N,
           Make_Attribute_Reference (Loc,
             Prefix         => New_Occurrence_Of (Temp_Id, Loc),
             Attribute_Name => Name_Unrestricted_Access));

         Analyze_And_Resolve (N, PtrT);
      end Rewrite_Coextension;

      ------------------------------
      -- Size_In_Storage_Elements --
      ------------------------------

      function Size_In_Storage_Elements (E : Entity_Id) return Node_Id is
      begin
         --  Logically this just returns E'Max_Size_In_Storage_Elements.
         --  However, the reason for the existence of this function is
         --  to construct a test for sizes too large, which means near the
         --  32-bit limit on a 32-bit machine, and precisely the trouble
         --  is that we get overflows when sizes are greater than 2**31.

         --  So what we end up doing for array types is to use the expression:

         --    number-of-elements * component_type'Max_Size_In_Storage_Elements

         --  which avoids this problem. All this is a bit bogus, but it does
         --  mean we catch common cases of trying to allocate arrays that
         --  are too large, and which in the absence of a check results in
         --  undetected chaos ???

         --  Note in particular that this is a pessimistic estimate in the
         --  case of packed array types, where an array element might occupy
         --  just a fraction of a storage element???

         declare
            Idx : Node_Id := First_Index (E);
            Len : Node_Id;
            Res : Node_Id;
            pragma Warnings (Off, Res);

         begin
            for J in 1 .. Number_Dimensions (E) loop

               if not Is_Modular_Integer_Type (Etype (Idx)) then
                  Len :=
                    Make_Attribute_Reference (Loc,
                      Prefix         => New_Occurrence_Of (E, Loc),
                      Attribute_Name => Name_Length,
                      Expressions    => New_List
                                          (Make_Integer_Literal (Loc, J)));

               --  For indexes that are modular types we cannot generate code
               --  to compute 'Length since for large arrays 'Last -'First + 1
               --  causes overflow; therefore we compute 'Last - 'First (which
               --  is not the exact number of components but it is valid for
               --  the purpose of this runtime check on 32-bit targets).

               else
                  declare
                     Len_Minus_1_Expr : Node_Id;
                     Test_Gt          : Node_Id;

                  begin
                     Test_Gt :=
                       Make_Op_Gt (Loc,
                         Make_Attribute_Reference (Loc,
                           Prefix         => New_Occurrence_Of (E, Loc),
                           Attribute_Name => Name_Last,
                           Expressions    =>
                             New_List (Make_Integer_Literal (Loc, J))),
                         Make_Attribute_Reference (Loc,
                           Prefix         => New_Occurrence_Of (E, Loc),
                           Attribute_Name => Name_First,
                           Expressions    =>
                             New_List (Make_Integer_Literal (Loc, J))));

                     Len_Minus_1_Expr :=
                       Convert_To (Standard_Unsigned,
                         Make_Op_Subtract (Loc,
                           Make_Attribute_Reference (Loc,
                             Prefix => New_Occurrence_Of (E, Loc),
                             Attribute_Name => Name_Last,
                             Expressions =>
                               New_List
                                 (Make_Integer_Literal (Loc, J))),
                           Make_Attribute_Reference (Loc,
                             Prefix => New_Occurrence_Of (E, Loc),
                             Attribute_Name => Name_First,
                             Expressions =>
                               New_List
                                 (Make_Integer_Literal (Loc, J)))));

                     --  Handle superflat arrays, i.e. arrays with such bounds
                     --  as 4 .. 2, to ensure that the result is correct.

                     --  Generate:
                     --    (if X'Last > X'First then X'Last - X'First else 0)

                     Len :=
                       Make_If_Expression (Loc,
                         Expressions => New_List (
                           Test_Gt,
                           Len_Minus_1_Expr,
                           Make_Integer_Literal (Loc, Uint_0)));
                  end;
               end if;

               if J = 1 then
                  Res := Len;

               else
                  Res :=
                    Make_Op_Multiply (Loc,
                      Left_Opnd  => Res,
                      Right_Opnd => Len);
               end if;

               Next_Index (Idx);
            end loop;

            return
              Make_Op_Multiply (Loc,
                Left_Opnd  => Len,
                Right_Opnd =>
                  Make_Attribute_Reference (Loc,
                    Prefix => New_Occurrence_Of (Component_Type (E), Loc),
                    Attribute_Name => Name_Max_Size_In_Storage_Elements));
         end;
      end Size_In_Storage_Elements;

      --  Local variables

      Dtyp    : constant Entity_Id := Available_View (Designated_Type (PtrT));
      Desig   : Entity_Id;
      Nod     : Node_Id;
      Pool    : Entity_Id;
      Rel_Typ : Entity_Id;
      Temp    : Entity_Id;

   --  Start of processing for Expand_N_Allocator

   begin
      --  Warn on the presence of an allocator of an anonymous access type when
      --  enabled, except when it's an object declaration at library level.

      if Warn_On_Anonymous_Allocators
        and then Ekind (PtrT) = E_Anonymous_Access_Type
        and then not (Is_Library_Level_Entity (PtrT)
                       and then Nkind (Associated_Node_For_Itype (PtrT)) =
                                  N_Object_Declaration)
      then
         Error_Msg_N ("?use of an anonymous access type allocator", N);
      end if;

      --  RM E.2.3(22). We enforce that the expected type of an allocator
      --  shall not be a remote access-to-class-wide-limited-private type

      --  Why is this being done at expansion time, seems clearly wrong ???

      Validate_Remote_Access_To_Class_Wide_Type (N);

      --  Processing for anonymous access-to-controlled types. These access
      --  types receive a special finalization master which appears in the
      --  declarations of the enclosing semantic unit. This expansion is done
      --  now to ensure that any additional types generated by this routine or
      --  Expand_Allocator_Expression inherit the proper type attributes.

      if (Ekind (PtrT) = E_Anonymous_Access_Type
           or else (Is_Itype (PtrT) and then No (Finalization_Master (PtrT))))
        and then Needs_Finalization (Dtyp)
      then
         --  Detect the allocation of an anonymous controlled object where the
         --  type of the context is named. For example:

         --     procedure Proc (Ptr : Named_Access_Typ);
         --     Proc (new Designated_Typ);

         --  Regardless of the anonymous-to-named access type conversion, the
         --  lifetime of the object must be associated with the named access
         --  type. Use the finalization-related attributes of this type.

         if Nkind_In (Parent (N), N_Type_Conversion,
                                  N_Unchecked_Type_Conversion)
           and then Ekind_In (Etype (Parent (N)), E_Access_Subtype,
                                                  E_Access_Type,
                                                  E_General_Access_Type)
         then
            Rel_Typ := Etype (Parent (N));
         else
            Rel_Typ := Empty;
         end if;

         --  Anonymous access-to-controlled types allocate on the global pool.
         --  Note that this is a "root type only" attribute.

         if No (Associated_Storage_Pool (PtrT)) then
            if Present (Rel_Typ) then
               Set_Associated_Storage_Pool
                 (Root_Type (PtrT), Associated_Storage_Pool (Rel_Typ));
            else
               Set_Associated_Storage_Pool
                 (Root_Type (PtrT), RTE (RE_Global_Pool_Object));
            end if;
         end if;

         --  The finalization master must be inserted and analyzed as part of
         --  the current semantic unit. Note that the master is updated when
         --  analysis changes current units. Note that this is a "root type
         --  only" attribute.

         if Present (Rel_Typ) then
            Set_Finalization_Master
              (Root_Type (PtrT), Finalization_Master (Rel_Typ));
         else
            Build_Anonymous_Master (Root_Type (PtrT));
         end if;
      end if;

      --  Set the storage pool and find the appropriate version of Allocate to
      --  call. Do not overwrite the storage pool if it is already set, which
      --  can happen for build-in-place function returns (see
      --  Exp_Ch4.Expand_N_Extended_Return_Statement).

      if No (Storage_Pool (N)) then
         Pool := Associated_Storage_Pool (Root_Type (PtrT));

         if Present (Pool) then
            Set_Storage_Pool (N, Pool);

            if Is_RTE (Pool, RE_SS_Pool) then
               Check_Restriction (No_Secondary_Stack, N);
               Set_Procedure_To_Call (N, RTE (RE_SS_Allocate));

            --  In the case of an allocator for a simple storage pool, locate
            --  and save a reference to the pool type's Allocate routine.

            elsif Present (Get_Rep_Pragma
                             (Etype (Pool), Name_Simple_Storage_Pool_Type))
            then
               declare
                  Pool_Type : constant Entity_Id := Base_Type (Etype (Pool));
                  Alloc_Op  : Entity_Id;
               begin
                  Alloc_Op := Get_Name_Entity_Id (Name_Allocate);
                  while Present (Alloc_Op) loop
                     if Scope (Alloc_Op) = Scope (Pool_Type)
                       and then Present (First_Formal (Alloc_Op))
                       and then Etype (First_Formal (Alloc_Op)) = Pool_Type
                     then
                        Set_Procedure_To_Call (N, Alloc_Op);
                        exit;
                     else
                        Alloc_Op := Homonym (Alloc_Op);
                     end if;
                  end loop;
               end;

            elsif Is_Class_Wide_Type (Etype (Pool)) then
               Set_Procedure_To_Call (N, RTE (RE_Allocate_Any));

            else
               Set_Procedure_To_Call (N,
                 Find_Prim_Op (Etype (Pool), Name_Allocate));
            end if;
         end if;
      end if;

      --  Under certain circumstances we can replace an allocator by an access
      --  to statically allocated storage. The conditions, as noted in AARM
      --  3.10 (10c) are as follows:

      --    Size and initial value is known at compile time
      --    Access type is access-to-constant

      --  The allocator is not part of a constraint on a record component,
      --  because in that case the inserted actions are delayed until the
      --  record declaration is fully analyzed, which is too late for the
      --  analysis of the rewritten allocator.

      if Is_Access_Constant (PtrT)
        and then Nkind (Expression (N)) = N_Qualified_Expression
        and then Compile_Time_Known_Value (Expression (Expression (N)))
        and then Size_Known_At_Compile_Time
                   (Etype (Expression (Expression (N))))
        and then not Is_Record_Type (Current_Scope)
      then
         --  Here we can do the optimization. For the allocator

         --    new x'(y)

         --  We insert an object declaration

         --    Tnn : aliased x := y;

         --  and replace the allocator by Tnn'Unrestricted_Access. Tnn is
         --  marked as requiring static allocation.

         Temp  := Make_Temporary (Loc, 'T', Expression (Expression (N)));
         Desig := Subtype_Mark (Expression (N));

         --  If context is constrained, use constrained subtype directly,
         --  so that the constant is not labelled as having a nominally
         --  unconstrained subtype.

         if Entity (Desig) = Base_Type (Dtyp) then
            Desig := New_Occurrence_Of (Dtyp, Loc);
         end if;

         Insert_Action (N,
           Make_Object_Declaration (Loc,
             Defining_Identifier => Temp,
             Aliased_Present     => True,
             Constant_Present    => Is_Access_Constant (PtrT),
             Object_Definition   => Desig,
             Expression          => Expression (Expression (N))));

         Rewrite (N,
           Make_Attribute_Reference (Loc,
             Prefix         => New_Occurrence_Of (Temp, Loc),
             Attribute_Name => Name_Unrestricted_Access));

         Analyze_And_Resolve (N, PtrT);

         --  We set the variable as statically allocated, since we don't want
         --  it going on the stack of the current procedure.

         Set_Is_Statically_Allocated (Temp);
         return;
      end if;

      --  Same if the allocator is an access discriminant for a local object:
      --  instead of an allocator we create a local value and constrain the
      --  enclosing object with the corresponding access attribute.

      if Is_Static_Coextension (N) then
         Rewrite_Coextension (N);
         return;
      end if;

      --  Check for size too large, we do this because the back end misses
      --  proper checks here and can generate rubbish allocation calls when
      --  we are near the limit. We only do this for the 32-bit address case
      --  since that is from a practical point of view where we see a problem.

      if System_Address_Size = 32
        and then not Storage_Checks_Suppressed (PtrT)
        and then not Storage_Checks_Suppressed (Dtyp)
        and then not Storage_Checks_Suppressed (Etyp)
      then
         --  The check we want to generate should look like

         --  if Etyp'Max_Size_In_Storage_Elements > 3.5 gigabytes then
         --    raise Storage_Error;
         --  end if;

         --  where 3.5 gigabytes is a constant large enough to accommodate any
         --  reasonable request for. But we can't do it this way because at
         --  least at the moment we don't compute this attribute right, and
         --  can silently give wrong results when the result gets large. Since
         --  this is all about large results, that's bad, so instead we only
         --  apply the check for constrained arrays, and manually compute the
         --  value of the attribute ???

         --  The check on No_Initialization is used here to prevent generating
         --  this runtime check twice when the allocator is locally replaced by
         --  the expander with another one.

         if Is_Array_Type (Etyp) and then not No_Initialization (N) then
            declare
               Cond    : Node_Id;
               Ins_Nod : Node_Id   := N;
               Siz_Typ : Entity_Id := Etyp;
               Expr    : Node_Id;

            begin
               --  For unconstrained array types initialized with a qualified
               --  expression we use its type to perform this check

               if not Is_Constrained (Etyp)
                 and then not No_Initialization (N)
                 and then Nkind (Expression (N)) = N_Qualified_Expression
               then
                  Expr    := Expression (Expression (N));
                  Siz_Typ := Etype (Expression (Expression (N)));

                  --  If the qualified expression has been moved to an internal
                  --  temporary (to remove side effects) then we must insert
                  --  the runtime check before its declaration to ensure that
                  --  the check is performed before the execution of the code
                  --  computing the qualified expression.

                  if Nkind (Expr) = N_Identifier
                    and then Is_Internal_Name (Chars (Expr))
                    and then
                      Nkind (Parent (Entity (Expr))) = N_Object_Declaration
                  then
                     Ins_Nod := Parent (Entity (Expr));
                  else
                     Ins_Nod := Expr;
                  end if;
               end if;

               if Is_Constrained (Siz_Typ)
                 and then Ekind (Siz_Typ) /= E_String_Literal_Subtype
               then
                  --  For CCG targets, the largest array may have up to 2**31-1
                  --  components (i.e. 2 gigabytes if each array component is
                  --  one byte). This ensures that fat pointer fields do not
                  --  overflow, since they are 32-bit integer types, and also
                  --  ensures that 'Length can be computed at run time.

                  if Modify_Tree_For_C then
                     Cond :=
                       Make_Op_Gt (Loc,
                         Left_Opnd  => Size_In_Storage_Elements (Siz_Typ),
                         Right_Opnd => Make_Integer_Literal (Loc,
                                         Uint_2 ** 31 - Uint_1));

                  --  For native targets the largest object is 3.5 gigabytes

                  else
                     Cond :=
                       Make_Op_Gt (Loc,
                         Left_Opnd  => Size_In_Storage_Elements (Siz_Typ),
                         Right_Opnd => Make_Integer_Literal (Loc,
                                         Uint_7 * (Uint_2 ** 29)));
                  end if;

                  Insert_Action (Ins_Nod,
                    Make_Raise_Storage_Error (Loc,
                      Condition => Cond,
                      Reason    => SE_Object_Too_Large));

                  if Entity (Cond) = Standard_True then
                     Error_Msg_N
                       ("object too large: Storage_Error will be raised at "
                        & "run time??", N);
                  end if;
               end if;
            end;
         end if;
      end if;

      --  If no storage pool has been specified, or the storage pool
      --  is System.Pool_Global.Global_Pool_Object, and the restriction
      --  No_Standard_Allocators_After_Elaboration is present, then generate
      --  a call to Elaboration_Allocators.Check_Standard_Allocator.

      if Nkind (N) = N_Allocator
        and then (No (Storage_Pool (N))
                   or else Is_RTE (Storage_Pool (N), RE_Global_Pool_Object))
        and then Restriction_Active (No_Standard_Allocators_After_Elaboration)
      then
         Insert_Action (N,
           Make_Procedure_Call_Statement (Loc,
             Name =>
               New_Occurrence_Of (RTE (RE_Check_Standard_Allocator), Loc)));
      end if;

      --  Handle case of qualified expression (other than optimization above)
      --  First apply constraint checks, because the bounds or discriminants
      --  in the aggregate might not match the subtype mark in the allocator.

      if Nkind (Expression (N)) = N_Qualified_Expression then
         declare
            Exp : constant Node_Id   := Expression (Expression (N));
            Typ : constant Entity_Id := Etype (Expression (N));

         begin
            Apply_Constraint_Check (Exp, Typ);
            Apply_Predicate_Check  (Exp, Typ);
         end;

         Expand_Allocator_Expression (N);
         return;
      end if;

      --  If the allocator is for a type which requires initialization, and
      --  there is no initial value (i.e. operand is a subtype indication
      --  rather than a qualified expression), then we must generate a call to
      --  the initialization routine using an expressions action node:

      --     [Pnnn : constant ptr_T := new (T); Init (Pnnn.all,...); Pnnn]

      --  Here ptr_T is the pointer type for the allocator, and T is the
      --  subtype of the allocator. A special case arises if the designated
      --  type of the access type is a task or contains tasks. In this case
      --  the call to Init (Temp.all ...) is replaced by code that ensures
      --  that tasks get activated (see Exp_Ch9.Build_Task_Allocate_Block
      --  for details). In addition, if the type T is a task type, then the
      --  first argument to Init must be converted to the task record type.

      declare
         T         : constant Entity_Id := Etype (Expression (N));
         Args      : List_Id;
         Decls     : List_Id;
         Decl      : Node_Id;
         Discr     : Elmt_Id;
         Init      : Entity_Id;
         Init_Arg1 : Node_Id;
         Init_Call : Node_Id;
         Temp_Decl : Node_Id;
         Temp_Type : Entity_Id;

      begin
         if No_Initialization (N) then

            --  Even though this might be a simple allocation, create a custom
            --  Allocate if the context requires it.

            if Present (Finalization_Master (PtrT)) then
               Build_Allocate_Deallocate_Proc
                 (N           => N,
                  Is_Allocate => True);
            end if;

         --  Optimize the default allocation of an array object when pragma
         --  Initialize_Scalars or Normalize_Scalars is in effect. Construct an
         --  in-place initialization aggregate which may be convert into a fast
         --  memset by the backend.

         elsif Init_Or_Norm_Scalars
           and then Is_Array_Type (T)

           --  The array must lack atomic components because they are treated
           --  as non-static, and as a result the backend will not initialize
           --  the memory in one go.

           and then not Has_Atomic_Components (T)

           --  The array must not be packed because the invalid values in
           --  System.Scalar_Values are multiples of Storage_Unit.

           and then not Is_Packed (T)

           --  The array must have static non-empty ranges, otherwise the
           --  backend cannot initialize the memory in one go.

           and then Has_Static_Non_Empty_Array_Bounds (T)

           --  The optimization is only relevant for arrays of scalar types

           and then Is_Scalar_Type (Component_Type (T))

           --  Similar to regular array initialization using a type init proc,
           --  predicate checks are not performed because the initialization
           --  values are intentionally invalid, and may violate the predicate.

           and then not Has_Predicates (Component_Type (T))

           --  The component type must have a single initialization value

           and then Needs_Simple_Initialization
                      (Typ         => Component_Type (T),
                       Consider_IS => True)
         then
            Set_Analyzed (N);
            Temp := Make_Temporary (Loc, 'P');

            --  Generate:
            --    Temp : Ptr_Typ := new ...;

            Insert_Action
              (Assoc_Node => N,
               Ins_Action =>
                 Make_Object_Declaration (Loc,
                   Defining_Identifier => Temp,
                   Object_Definition   => New_Occurrence_Of (PtrT, Loc),
                   Expression          => Relocate_Node (N)),
               Suppress   => All_Checks);

            --  Generate:
            --    Temp.all := (others => ...);

            Insert_Action
              (Assoc_Node => N,
               Ins_Action =>
                 Make_Assignment_Statement (Loc,
                   Name       =>
                     Make_Explicit_Dereference (Loc,
                       Prefix => New_Occurrence_Of (Temp, Loc)),
                   Expression =>
                     Get_Simple_Init_Val
                       (Typ  => T,
                        N    => N,
                        Size => Esize (Component_Type (T)))),
               Suppress   => All_Checks);

            Rewrite (N, New_Occurrence_Of (Temp, Loc));
            Analyze_And_Resolve (N, PtrT);

         --  Case of no initialization procedure present

         elsif not Has_Non_Null_Base_Init_Proc (T) then

            --  Case of simple initialization required

            if Needs_Simple_Initialization (T) then
               Check_Restriction (No_Default_Initialization, N);
               Rewrite (Expression (N),
                 Make_Qualified_Expression (Loc,
                   Subtype_Mark => New_Occurrence_Of (T, Loc),
                   Expression   => Get_Simple_Init_Val (T, N)));

               Analyze_And_Resolve (Expression (Expression (N)), T);
               Analyze_And_Resolve (Expression (N), T);
               Set_Paren_Count     (Expression (Expression (N)), 1);
               Expand_N_Allocator  (N);

            --  No initialization required

            else
               Build_Allocate_Deallocate_Proc
                 (N           => N,
                  Is_Allocate => True);
            end if;

         --  Case of initialization procedure present, must be called

         --  NOTE: There is a *huge* amount of code duplication here from
         --  Build_Initialization_Call. We should probably refactor???

         else
            Check_Restriction (No_Default_Initialization, N);

            if not Restriction_Active (No_Default_Initialization) then
               Init := Base_Init_Proc (T);
               Nod  := N;
               Temp := Make_Temporary (Loc, 'P');

               --  Construct argument list for the initialization routine call

               Init_Arg1 :=
                 Make_Explicit_Dereference (Loc,
                   Prefix =>
                     New_Occurrence_Of (Temp, Loc));

               Set_Assignment_OK (Init_Arg1);
               Temp_Type := PtrT;

               --  The initialization procedure expects a specific type. if the
               --  context is access to class wide, indicate that the object
               --  being allocated has the right specific type.

               if Is_Class_Wide_Type (Dtyp) then
                  Init_Arg1 := Unchecked_Convert_To (T, Init_Arg1);
               end if;

               --  If designated type is a concurrent type or if it is private
               --  type whose definition is a concurrent type, the first
               --  argument in the Init routine has to be unchecked conversion
               --  to the corresponding record type. If the designated type is
               --  a derived type, also convert the argument to its root type.

               if Is_Concurrent_Type (T) then
                  Init_Arg1 :=
                    Unchecked_Convert_To (
                      Corresponding_Record_Type (T), Init_Arg1);

               elsif Is_Private_Type (T)
                 and then Present (Full_View (T))
                 and then Is_Concurrent_Type (Full_View (T))
               then
                  Init_Arg1 :=
                    Unchecked_Convert_To
                      (Corresponding_Record_Type (Full_View (T)), Init_Arg1);

               elsif Etype (First_Formal (Init)) /= Base_Type (T) then
                  declare
                     Ftyp : constant Entity_Id := Etype (First_Formal (Init));

                  begin
                     Init_Arg1 := OK_Convert_To (Etype (Ftyp), Init_Arg1);
                     Set_Etype (Init_Arg1, Ftyp);
                  end;
               end if;

               Args := New_List (Init_Arg1);

               --  For the task case, pass the Master_Id of the access type as
               --  the value of the _Master parameter, and _Chain as the value
               --  of the _Chain parameter (_Chain will be defined as part of
               --  the generated code for the allocator).

               --  In Ada 2005, the context may be a function that returns an
               --  anonymous access type. In that case the Master_Id has been
               --  created when expanding the function declaration.

               if Has_Task (T) then
                  if No (Master_Id (Base_Type (PtrT))) then

                     --  The designated type was an incomplete type, and the
                     --  access type did not get expanded. Salvage it now.

                     if not Restriction_Active (No_Task_Hierarchy) then
                        if Present (Parent (Base_Type (PtrT))) then
                           Expand_N_Full_Type_Declaration
                             (Parent (Base_Type (PtrT)));

                        --  The only other possibility is an itype. For this
                        --  case, the master must exist in the context. This is
                        --  the case when the allocator initializes an access
                        --  component in an init-proc.

                        else
                           pragma Assert (Is_Itype (PtrT));
                           Build_Master_Renaming (PtrT, N);
                        end if;
                     end if;
                  end if;

                  --  If the context of the allocator is a declaration or an
                  --  assignment, we can generate a meaningful image for it,
                  --  even though subsequent assignments might remove the
                  --  connection between task and entity. We build this image
                  --  when the left-hand side is a simple variable, a simple
                  --  indexed assignment or a simple selected component.

                  if Nkind (Parent (N)) = N_Assignment_Statement then
                     declare
                        Nam : constant Node_Id := Name (Parent (N));

                     begin
                        if Is_Entity_Name (Nam) then
                           Decls :=
                             Build_Task_Image_Decls
                               (Loc,
                                New_Occurrence_Of
                                  (Entity (Nam), Sloc (Nam)), T);

                        elsif Nkind_In (Nam, N_Indexed_Component,
                                             N_Selected_Component)
                          and then Is_Entity_Name (Prefix (Nam))
                        then
                           Decls :=
                             Build_Task_Image_Decls
                               (Loc, Nam, Etype (Prefix (Nam)));
                        else
                           Decls := Build_Task_Image_Decls (Loc, T, T);
                        end if;
                     end;

                  elsif Nkind (Parent (N)) = N_Object_Declaration then
                     Decls :=
                       Build_Task_Image_Decls
                         (Loc, Defining_Identifier (Parent (N)), T);

                  else
                     Decls := Build_Task_Image_Decls (Loc, T, T);
                  end if;

                  if Restriction_Active (No_Task_Hierarchy) then
                     Append_To (Args,
                       New_Occurrence_Of (RTE (RE_Library_Task_Level), Loc));
                  else
                     Append_To (Args,
                       New_Occurrence_Of
                         (Master_Id (Base_Type (Root_Type (PtrT))), Loc));
                  end if;

                  Append_To (Args, Make_Identifier (Loc, Name_uChain));

                  Decl := Last (Decls);
                  Append_To (Args,
                    New_Occurrence_Of (Defining_Identifier (Decl), Loc));

               --  Has_Task is false, Decls not used

               else
                  Decls := No_List;
               end if;

               --  Add discriminants if discriminated type

               declare
                  Dis : Boolean := False;
                  Typ : Entity_Id := Empty;

               begin
                  if Has_Discriminants (T) then
                     Dis := True;
                     Typ := T;

                  --  Type may be a private type with no visible discriminants
                  --  in which case check full view if in scope, or the
                  --  underlying_full_view if dealing with a type whose full
                  --  view may be derived from a private type whose own full
                  --  view has discriminants.

                  elsif Is_Private_Type (T) then
                     if Present (Full_View (T))
                       and then Has_Discriminants (Full_View (T))
                     then
                        Dis := True;
                        Typ := Full_View (T);

                     elsif Present (Underlying_Full_View (T))
                       and then Has_Discriminants (Underlying_Full_View (T))
                     then
                        Dis := True;
                        Typ := Underlying_Full_View (T);
                     end if;
                  end if;

                  if Dis then

                     --  If the allocated object will be constrained by the
                     --  default values for discriminants, then build a subtype
                     --  with those defaults, and change the allocated subtype
                     --  to that. Note that this happens in fewer cases in Ada
                     --  2005 (AI-363).

                     if not Is_Constrained (Typ)
                       and then Present (Discriminant_Default_Value
                                          (First_Discriminant (Typ)))
                       and then (Ada_Version < Ada_2005
                                  or else not
                                    Object_Type_Has_Constrained_Partial_View
                                      (Typ, Current_Scope))
                     then
                        Typ := Build_Default_Subtype (Typ, N);
                        Set_Expression (N, New_Occurrence_Of (Typ, Loc));
                     end if;

                     Discr := First_Elmt (Discriminant_Constraint (Typ));
                     while Present (Discr) loop
                        Nod := Node (Discr);
                        Append (New_Copy_Tree (Node (Discr)), Args);

                        --  AI-416: when the discriminant constraint is an
                        --  anonymous access type make sure an accessibility
                        --  check is inserted if necessary (3.10.2(22.q/2))

                        if Ada_Version >= Ada_2005
                          and then
                            Ekind (Etype (Nod)) = E_Anonymous_Access_Type
                        then
                           Apply_Accessibility_Check
                             (Nod, Typ, Insert_Node => Nod);
                        end if;

                        Next_Elmt (Discr);
                     end loop;
                  end if;
               end;

               --  We set the allocator as analyzed so that when we analyze
               --  the if expression node, we do not get an unwanted recursive
               --  expansion of the allocator expression.

               Set_Analyzed (N, True);
               Nod := Relocate_Node (N);

               --  Here is the transformation:
               --    input:  new Ctrl_Typ
               --    output: Temp : constant Ctrl_Typ_Ptr := new Ctrl_Typ;
               --            Ctrl_TypIP (Temp.all, ...);
               --            [Deep_]Initialize (Temp.all);

               --  Here Ctrl_Typ_Ptr is the pointer type for the allocator, and
               --  is the subtype of the allocator.

               Temp_Decl :=
                 Make_Object_Declaration (Loc,
                   Defining_Identifier => Temp,
                   Constant_Present    => True,
                   Object_Definition   => New_Occurrence_Of (Temp_Type, Loc),
                   Expression          => Nod);

               Set_Assignment_OK (Temp_Decl);
               Insert_Action (N, Temp_Decl, Suppress => All_Checks);

               Build_Allocate_Deallocate_Proc (Temp_Decl, True);

               --  If the designated type is a task type or contains tasks,
               --  create block to activate created tasks, and insert
               --  declaration for Task_Image variable ahead of call.

               if Has_Task (T) then
                  declare
                     L   : constant List_Id := New_List;
                     Blk : Node_Id;
                  begin
                     Build_Task_Allocate_Block (L, Nod, Args);
                     Blk := Last (L);
                     Insert_List_Before (First (Declarations (Blk)), Decls);
                     Insert_Actions (N, L);
                  end;

               else
                  Insert_Action (N,
                    Make_Procedure_Call_Statement (Loc,
                      Name                   => New_Occurrence_Of (Init, Loc),
                      Parameter_Associations => Args));
               end if;

               if Needs_Finalization (T) then

                  --  Generate:
                  --    [Deep_]Initialize (Init_Arg1);

                  Init_Call :=
                    Make_Init_Call
                      (Obj_Ref => New_Copy_Tree (Init_Arg1),
                       Typ     => T);

                  --  Guard against a missing [Deep_]Initialize when the
                  --  designated type was not properly frozen.

                  if Present (Init_Call) then
                     Insert_Action (N, Init_Call);
                  end if;
               end if;

               Rewrite (N, New_Occurrence_Of (Temp, Loc));
               Analyze_And_Resolve (N, PtrT);
            end if;
         end if;
      end;

      --  Ada 2005 (AI-251): If the allocator is for a class-wide interface
      --  object that has been rewritten as a reference, we displace "this"
      --  to reference properly its secondary dispatch table.

      if Nkind (N) = N_Identifier and then Is_Interface (Dtyp) then
         Displace_Allocator_Pointer (N);
      end if;

   exception
      when RE_Not_Available =>
         return;
   end Expand_N_Allocator;

   -----------------------
   -- Expand_N_And_Then --
   -----------------------

   procedure Expand_N_And_Then (N : Node_Id)
     renames Expand_Short_Circuit_Operator;

   ------------------------------
   -- Expand_N_Case_Expression --
   ------------------------------

   procedure Expand_N_Case_Expression (N : Node_Id) is
      function Is_Copy_Type (Typ : Entity_Id) return Boolean;
      --  Return True if we can copy objects of this type when expanding a case
      --  expression.

      ------------------
      -- Is_Copy_Type --
      ------------------

      function Is_Copy_Type (Typ : Entity_Id) return Boolean is
      begin
         --  If Minimize_Expression_With_Actions is True, we can afford to copy
         --  large objects, as long as they are constrained and not limited.

         return
           Is_Elementary_Type (Underlying_Type (Typ))
             or else
               (Minimize_Expression_With_Actions
                 and then Is_Constrained (Underlying_Type (Typ))
                 and then not Is_Limited_Type (Underlying_Type (Typ)));
      end Is_Copy_Type;

      --  Local variables

      Loc : constant Source_Ptr := Sloc (N);
      Par : constant Node_Id    := Parent (N);
      Typ : constant Entity_Id  := Etype (N);

      Acts       : List_Id;
      Alt        : Node_Id;
      Case_Stmt  : Node_Id;
      Decl       : Node_Id;
      Expr       : Node_Id;
      Target     : Entity_Id;
      Target_Typ : Entity_Id;

      In_Predicate : Boolean := False;
      --  Flag set when the case expression appears within a predicate

      Optimize_Return_Stmt : Boolean := False;
      --  Flag set when the case expression can be optimized in the context of
      --  a simple return statement.

   --  Start of processing for Expand_N_Case_Expression

   begin
      --  Check for MINIMIZED/ELIMINATED overflow mode

      if Minimized_Eliminated_Overflow_Check (N) then
         Apply_Arithmetic_Overflow_Check (N);
         return;
      end if;

      --  If the case expression is a predicate specification, and the type
      --  to which it applies has a static predicate aspect, do not expand,
      --  because it will be converted to the proper predicate form later.

      if Ekind_In (Current_Scope, E_Function, E_Procedure)
        and then Is_Predicate_Function (Current_Scope)
      then
         In_Predicate := True;

         if Has_Static_Predicate_Aspect (Etype (First_Entity (Current_Scope)))
         then
            return;
         end if;
      end if;

      --  When the type of the case expression is elementary, expand

      --    (case X is when A => AX, when B => BX ...)

      --  into

      --    do
      --       Target : Typ;
      --       case X is
      --          when A =>
      --             Target := AX;
      --          when B =>
      --             Target := BX;
      --          ...
      --       end case;
      --    in Target end;

      --  In all other cases expand into

      --    do
      --       type Ptr_Typ is access all Typ;
      --       Target : Ptr_Typ;
      --       case X is
      --          when A =>
      --             Target := AX'Unrestricted_Access;
      --          when B =>
      --             Target := BX'Unrestricted_Access;
      --          ...
      --       end case;
      --    in Target.all end;

      --  This approach avoids extra copies of potentially large objects. It
      --  also allows handling of values of limited or unconstrained types.
      --  Note that we do the copy also for constrained, nonlimited types
      --  when minimizing expressions with actions (e.g. when generating C
      --  code) since it allows us to do the optimization below in more cases.

      --  Small optimization: when the case expression appears in the context
      --  of a simple return statement, expand into

      --    case X is
      --       when A =>
      --          return AX;
      --       when B =>
      --          return BX;
      --       ...
      --    end case;

      Case_Stmt :=
        Make_Case_Statement (Loc,
          Expression   => Expression (N),
          Alternatives => New_List);

      --  Preserve the original context for which the case statement is being
      --  generated. This is needed by the finalization machinery to prevent
      --  the premature finalization of controlled objects found within the
      --  case statement.

      Set_From_Conditional_Expression (Case_Stmt);
      Acts := New_List;

      --  Scalar/Copy case

      if Is_Copy_Type (Typ) then
         Target_Typ := Typ;

         --  ??? Do not perform the optimization when the return statement is
         --  within a predicate function, as this causes spurious errors. Could
         --  this be a possible mismatch in handling this case somewhere else
         --  in semantic analysis?

         Optimize_Return_Stmt :=
           Nkind (Par) = N_Simple_Return_Statement and then not In_Predicate;

      --  Otherwise create an access type to handle the general case using
      --  'Unrestricted_Access.

      --  Generate:
      --    type Ptr_Typ is access all Typ;

      else
         if Generate_C_Code then

            --  We cannot ensure that correct C code will be generated if any
            --  temporary is created down the line (to e.g. handle checks or
            --  capture values) since we might end up with dangling references
            --  to local variables, so better be safe and reject the construct.

            Error_Msg_N
              ("case expression too complex, use case statement instead", N);
         end if;

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

         Append_To (Acts,
           Make_Full_Type_Declaration (Loc,
             Defining_Identifier => Target_Typ,
             Type_Definition     =>
               Make_Access_To_Object_Definition (Loc,
                 All_Present        => True,
                 Subtype_Indication => New_Occurrence_Of (Typ, Loc))));
      end if;

      --  Create the declaration of the target which captures the value of the
      --  expression.

      --  Generate:
      --    Target : [Ptr_]Typ;

      if not Optimize_Return_Stmt then
         Target := Make_Temporary (Loc, 'T');

         Decl :=
           Make_Object_Declaration (Loc,
             Defining_Identifier => Target,
             Object_Definition   => New_Occurrence_Of (Target_Typ, Loc));
         Set_No_Initialization (Decl);

         Append_To (Acts, Decl);
      end if;

      --  Process the alternatives

      Alt := First (Alternatives (N));
      while Present (Alt) loop
         declare
            Alt_Expr : Node_Id             := Expression (Alt);
            Alt_Loc  : constant Source_Ptr := Sloc (Alt_Expr);
            LHS      : Node_Id;
            Stmts    : List_Id;

         begin
            --  Take the unrestricted access of the expression value for non-
            --  scalar types. This approach avoids big copies and covers the
            --  limited and unconstrained cases.

            --  Generate:
            --    AX'Unrestricted_Access

            if not Is_Copy_Type (Typ) then
               Alt_Expr :=
                 Make_Attribute_Reference (Alt_Loc,
                   Prefix         => Relocate_Node (Alt_Expr),
                   Attribute_Name => Name_Unrestricted_Access);
            end if;

            --  Generate:
            --    return AX['Unrestricted_Access];

            if Optimize_Return_Stmt then
               Stmts := New_List (
                 Make_Simple_Return_Statement (Alt_Loc,
                   Expression => Alt_Expr));

            --  Generate:
            --    Target := AX['Unrestricted_Access];

            else
               LHS := New_Occurrence_Of (Target, Loc);
               Set_Assignment_OK (LHS);

               Stmts := New_List (
                 Make_Assignment_Statement (Alt_Loc,
                   Name       => LHS,
                   Expression => Alt_Expr));
            end if;

            --  Propagate declarations inserted in the node by Insert_Actions
            --  (for example, temporaries generated to remove side effects).
            --  These actions must remain attached to the alternative, given
            --  that they are generated by the corresponding expression.

            if Present (Actions (Alt)) then
               Prepend_List (Actions (Alt), Stmts);
            end if;

            --  Finalize any transient objects on exit from the alternative.
            --  This is done only in the return optimization case because
            --  otherwise the case expression is converted into an expression
            --  with actions which already contains this form of processing.

            if Optimize_Return_Stmt then
               Process_If_Case_Statements (N, Stmts);
            end if;

            Append_To
              (Alternatives (Case_Stmt),
               Make_Case_Statement_Alternative (Sloc (Alt),
                 Discrete_Choices => Discrete_Choices (Alt),
                 Statements       => Stmts));
         end;

         Next (Alt);
      end loop;

      --  Rewrite the parent return statement as a case statement

      if Optimize_Return_Stmt then
         Rewrite (Par, Case_Stmt);
         Analyze (Par);

      --  Otherwise convert the case expression into an expression with actions

      else
         Append_To (Acts, Case_Stmt);

         if Is_Copy_Type (Typ) then
            Expr := New_Occurrence_Of (Target, Loc);

         else
            Expr :=
              Make_Explicit_Dereference (Loc,
                Prefix => New_Occurrence_Of (Target, Loc));
         end if;

         --  Generate:
         --    do
         --       ...
         --    in Target[.all] end;

         Rewrite (N,
           Make_Expression_With_Actions (Loc,
             Expression => Expr,
             Actions    => Acts));

         Analyze_And_Resolve (N, Typ);
      end if;
   end Expand_N_Case_Expression;

   -----------------------------------
   -- Expand_N_Explicit_Dereference --
   -----------------------------------

   procedure Expand_N_Explicit_Dereference (N : Node_Id) is
   begin
      --  Insert explicit dereference call for the checked storage pool case

      Insert_Dereference_Action (Prefix (N));

      --  If the type is an Atomic type for which Atomic_Sync is enabled, then
      --  we set the atomic sync flag.

      if Is_Atomic (Etype (N))
        and then not Atomic_Synchronization_Disabled (Etype (N))
      then
         Activate_Atomic_Synchronization (N);
      end if;
   end Expand_N_Explicit_Dereference;

   --------------------------------------
   -- Expand_N_Expression_With_Actions --
   --------------------------------------

   procedure Expand_N_Expression_With_Actions (N : Node_Id) is
      Acts : constant List_Id := Actions (N);

      procedure Force_Boolean_Evaluation (Expr : Node_Id);
      --  Force the evaluation of Boolean expression Expr

      function Process_Action (Act : Node_Id) return Traverse_Result;
      --  Inspect and process a single action of an expression_with_actions for
      --  transient objects. If such objects are found, the routine generates
      --  code to clean them up when the context of the expression is evaluated
      --  or elaborated.

      ------------------------------
      -- Force_Boolean_Evaluation --
      ------------------------------

      procedure Force_Boolean_Evaluation (Expr : Node_Id) is
         Loc       : constant Source_Ptr := Sloc (N);
         Flag_Decl : Node_Id;
         Flag_Id   : Entity_Id;

      begin
         --  Relocate the expression to the actions list by capturing its value
         --  in a Boolean flag. Generate:
         --    Flag : constant Boolean := Expr;

         Flag_Id := Make_Temporary (Loc, 'F');

         Flag_Decl :=
           Make_Object_Declaration (Loc,
             Defining_Identifier => Flag_Id,
             Constant_Present    => True,
             Object_Definition   => New_Occurrence_Of (Standard_Boolean, Loc),
             Expression          => Relocate_Node (Expr));

         Append (Flag_Decl, Acts);
         Analyze (Flag_Decl);

         --  Replace the expression with a reference to the flag

         Rewrite (Expression (N), New_Occurrence_Of (Flag_Id, Loc));
         Analyze (Expression (N));
      end Force_Boolean_Evaluation;

      --------------------
      -- Process_Action --
      --------------------

      function Process_Action (Act : Node_Id) return Traverse_Result is
      begin
         if Nkind (Act) = N_Object_Declaration
           and then Is_Finalizable_Transient (Act, N)
         then
            Process_Transient_In_Expression (Act, N, Acts);
            return Skip;

         --  Avoid processing temporary function results multiple times when
         --  dealing with nested expression_with_actions.

         elsif Nkind (Act) = N_Expression_With_Actions then
            return Abandon;

         --  Do not process temporary function results in loops. This is done
         --  by Expand_N_Loop_Statement and Build_Finalizer.

         elsif Nkind (Act) = N_Loop_Statement then
            return Abandon;
         end if;

         return OK;
      end Process_Action;

      procedure Process_Single_Action is new Traverse_Proc (Process_Action);

      --  Local variables

      Act : Node_Id;

   --  Start of processing for Expand_N_Expression_With_Actions

   begin
      --  Do not evaluate the expression when it denotes an entity because the
      --  expression_with_actions node will be replaced by the reference.

      if Is_Entity_Name (Expression (N)) then
         null;

      --  Do not evaluate the expression when there are no actions because the
      --  expression_with_actions node will be replaced by the expression.

      elsif No (Acts) or else Is_Empty_List (Acts) then
         null;

      --  Force the evaluation of the expression by capturing its value in a
      --  temporary. This ensures that aliases of transient objects do not leak
      --  to the expression of the expression_with_actions node:

      --    do
      --       Trans_Id : Ctrl_Typ := ...;
      --       Alias : ... := Trans_Id;
      --    in ... Alias ... end;

      --  In the example above, Trans_Id cannot be finalized at the end of the
      --  actions list because this may affect the alias and the final value of
      --  the expression_with_actions. Forcing the evaluation encapsulates the
      --  reference to the Alias within the actions list:

      --    do
      --       Trans_Id : Ctrl_Typ := ...;
      --       Alias : ... := Trans_Id;
      --       Val : constant Boolean := ... Alias ...;
      --       <finalize Trans_Id>
      --    in Val end;

      --  Once this transformation is performed, it is safe to finalize the
      --  transient object at the end of the actions list.

      --  Note that Force_Evaluation does not remove side effects in operators
      --  because it assumes that all operands are evaluated and side effect
      --  free. This is not the case when an operand depends implicitly on the
      --  transient object through the use of access types.

      elsif Is_Boolean_Type (Etype (Expression (N))) then
         Force_Boolean_Evaluation (Expression (N));

      --  The expression of an expression_with_actions node may not necessarily
      --  be Boolean when the node appears in an if expression. In this case do
      --  the usual forced evaluation to encapsulate potential aliasing.

      else
         Force_Evaluation (Expression (N));
      end if;

      --  Process all transient objects found within the actions of the EWA
      --  node.

      Act := First (Acts);
      while Present (Act) loop
         Process_Single_Action (Act);
         Next (Act);
      end loop;

      --  Deal with case where there are no actions. In this case we simply
      --  rewrite the node with its expression since we don't need the actions
      --  and the specification of this node does not allow a null action list.

      --  Note: we use Rewrite instead of Replace, because Codepeer is using
      --  the expanded tree and relying on being able to retrieve the original
      --  tree in cases like this. This raises a whole lot of issues of whether
      --  we have problems elsewhere, which will be addressed in the future???

      if Is_Empty_List (Acts) then
         Rewrite (N, Relocate_Node (Expression (N)));
      end if;
   end Expand_N_Expression_With_Actions;

   ----------------------------
   -- Expand_N_If_Expression --
   ----------------------------

   --  Deal with limited types and condition actions

   procedure Expand_N_If_Expression (N : Node_Id) is
      Cond  : constant Node_Id    := First (Expressions (N));
      Loc   : constant Source_Ptr := Sloc (N);
      Thenx : constant Node_Id    := Next (Cond);
      Elsex : constant Node_Id    := Next (Thenx);
      Typ   : constant Entity_Id  := Etype (N);

      Actions : List_Id;
      Decl    : Node_Id;
      Expr    : Node_Id;
      New_If  : Node_Id;
      New_N   : Node_Id;

   begin
      --  Check for MINIMIZED/ELIMINATED overflow mode

      if Minimized_Eliminated_Overflow_Check (N) then
         Apply_Arithmetic_Overflow_Check (N);
         return;
      end if;

      --  Fold at compile time if condition known. We have already folded
      --  static if expressions, but it is possible to fold any case in which
      --  the condition is known at compile time, even though the result is
      --  non-static.

      --  Note that we don't do the fold of such cases in Sem_Elab because
      --  it can cause infinite loops with the expander adding a conditional
      --  expression, and Sem_Elab circuitry removing it repeatedly.

      if Compile_Time_Known_Value (Cond) then
         declare
            function Fold_Known_Value (Cond : Node_Id) return Boolean;
            --  Fold at compile time. Assumes condition known. Return True if
            --  folding occurred, meaning we're done.

            ----------------------
            -- Fold_Known_Value --
            ----------------------

            function Fold_Known_Value (Cond : Node_Id) return Boolean is
            begin
               if Is_True (Expr_Value (Cond)) then
                  Expr    := Thenx;
                  Actions := Then_Actions (N);
               else
                  Expr    := Elsex;
                  Actions := Else_Actions (N);
               end if;

               Remove (Expr);

               if Present (Actions) then

                  --  To minimize the use of Expression_With_Actions, just skip
                  --  the optimization as it is not critical for correctness.

                  if Minimize_Expression_With_Actions then
                     return False;
                  end if;

                  Rewrite (N,
                    Make_Expression_With_Actions (Loc,
                      Expression => Relocate_Node (Expr),
                      Actions    => Actions));
                  Analyze_And_Resolve (N, Typ);

               else
                  Rewrite (N, Relocate_Node (Expr));
               end if;

               --  Note that the result is never static (legitimate cases of
               --  static if expressions were folded in Sem_Eval).

               Set_Is_Static_Expression (N, False);
               return True;
            end Fold_Known_Value;

         begin
            if Fold_Known_Value (Cond) then
               return;
            end if;
         end;
      end if;

      --  If the type is limited, and the back end does not handle limited
      --  types, then we expand as follows to avoid the possibility of
      --  improper copying.

      --      type Ptr is access all Typ;
      --      Cnn : Ptr;
      --      if cond then
      --         <<then actions>>
      --         Cnn := then-expr'Unrestricted_Access;
      --      else
      --         <<else actions>>
      --         Cnn := else-expr'Unrestricted_Access;
      --      end if;

      --  and replace the if expression by a reference to Cnn.all.

      --  This special case can be skipped if the back end handles limited
      --  types properly and ensures that no incorrect copies are made.

      if Is_By_Reference_Type (Typ)
        and then not Back_End_Handles_Limited_Types
      then
         --  When the "then" or "else" expressions involve controlled function
         --  calls, generated temporaries are chained on the corresponding list
         --  of actions. These temporaries need to be finalized after the if
         --  expression is evaluated.

         Process_If_Case_Statements (N, Then_Actions (N));
         Process_If_Case_Statements (N, Else_Actions (N));

         declare
            Cnn     : constant Entity_Id := Make_Temporary (Loc, 'C', N);
            Ptr_Typ : constant Entity_Id := Make_Temporary (Loc, 'A');

         begin
            --  Generate:
            --    type Ann is access all Typ;

            Insert_Action (N,
              Make_Full_Type_Declaration (Loc,
                Defining_Identifier => Ptr_Typ,
                Type_Definition     =>
                  Make_Access_To_Object_Definition (Loc,
                    All_Present        => True,
                    Subtype_Indication => New_Occurrence_Of (Typ, Loc))));

            --  Generate:
            --    Cnn : Ann;

            Decl :=
              Make_Object_Declaration (Loc,
                Defining_Identifier => Cnn,
                Object_Definition   => New_Occurrence_Of (Ptr_Typ, Loc));

            --  Generate:
            --    if Cond then
            --       Cnn := <Thenx>'Unrestricted_Access;
            --    else
            --       Cnn := <Elsex>'Unrestricted_Access;
            --    end if;

            New_If :=
              Make_Implicit_If_Statement (N,
                Condition       => Relocate_Node (Cond),
                Then_Statements => New_List (
                  Make_Assignment_Statement (Sloc (Thenx),
                    Name       => New_Occurrence_Of (Cnn, Sloc (Thenx)),
                    Expression =>
                      Make_Attribute_Reference (Loc,
                        Prefix         => Relocate_Node (Thenx),
                        Attribute_Name => Name_Unrestricted_Access))),

                Else_Statements => New_List (
                  Make_Assignment_Statement (Sloc (Elsex),
                    Name       => New_Occurrence_Of (Cnn, Sloc (Elsex)),
                    Expression =>
                      Make_Attribute_Reference (Loc,
                        Prefix         => Relocate_Node (Elsex),
                        Attribute_Name => Name_Unrestricted_Access))));

            --  Preserve the original context for which the if statement is
            --  being generated. This is needed by the finalization machinery
            --  to prevent the premature finalization of controlled objects
            --  found within the if statement.

            Set_From_Conditional_Expression (New_If);

            New_N :=
              Make_Explicit_Dereference (Loc,
                Prefix => New_Occurrence_Of (Cnn, Loc));
         end;

      --  If the result is an unconstrained array and the if expression is in a
      --  context other than the initializing expression of the declaration of
      --  an object, then we pull out the if expression as follows:

      --     Cnn : constant typ := if-expression

      --  and then replace the if expression with an occurrence of Cnn. This
      --  avoids the need in the back end to create on-the-fly variable length
      --  temporaries (which it cannot do!)

      --  Note that the test for being in an object declaration avoids doing an
      --  unnecessary expansion, and also avoids infinite recursion.

      elsif Is_Array_Type (Typ) and then not Is_Constrained (Typ)
        and then (Nkind (Parent (N)) /= N_Object_Declaration
                   or else Expression (Parent (N)) /= N)
      then
         declare
            Cnn : constant Node_Id := Make_Temporary (Loc, 'C', N);

         begin
            Insert_Action (N,
              Make_Object_Declaration (Loc,
                Defining_Identifier => Cnn,
                Constant_Present    => True,
                Object_Definition   => New_Occurrence_Of (Typ, Loc),
                Expression          => Relocate_Node (N),
                Has_Init_Expression => True));

            Rewrite (N, New_Occurrence_Of (Cnn, Loc));
            return;
         end;

      --  For other types, we only need to expand if there are other actions
      --  associated with either branch.

      elsif Present (Then_Actions (N)) or else Present (Else_Actions (N)) then

         --  We now wrap the actions into the appropriate expression

         if Minimize_Expression_With_Actions
           and then (Is_Elementary_Type (Underlying_Type (Typ))
                      or else Is_Constrained (Underlying_Type (Typ)))
         then
            --  If we can't use N_Expression_With_Actions nodes, then we insert
            --  the following sequence of actions (using Insert_Actions):

            --      Cnn : typ;
            --      if cond then
            --         <<then actions>>
            --         Cnn := then-expr;
            --      else
            --         <<else actions>>
            --         Cnn := else-expr
            --      end if;

            --  and replace the if expression by a reference to Cnn

            declare
               Cnn : constant Node_Id := Make_Temporary (Loc, 'C', N);

            begin
               Decl :=
                 Make_Object_Declaration (Loc,
                   Defining_Identifier => Cnn,
                   Object_Definition   => New_Occurrence_Of (Typ, Loc));

               New_If :=
                 Make_Implicit_If_Statement (N,
                   Condition       => Relocate_Node (Cond),

                   Then_Statements => New_List (
                     Make_Assignment_Statement (Sloc (Thenx),
                       Name       => New_Occurrence_Of (Cnn, Sloc (Thenx)),
                       Expression => Relocate_Node (Thenx))),

                   Else_Statements => New_List (
                     Make_Assignment_Statement (Sloc (Elsex),
                       Name       => New_Occurrence_Of (Cnn, Sloc (Elsex)),
                       Expression => Relocate_Node (Elsex))));

               Set_Assignment_OK (Name (First (Then_Statements (New_If))));
               Set_Assignment_OK (Name (First (Else_Statements (New_If))));

               New_N := New_Occurrence_Of (Cnn, Loc);
            end;

         --  Regular path using Expression_With_Actions

         else
            if Present (Then_Actions (N)) then
               Rewrite (Thenx,
                 Make_Expression_With_Actions (Sloc (Thenx),
                   Actions    => Then_Actions (N),
                   Expression => Relocate_Node (Thenx)));

               Set_Then_Actions (N, No_List);
               Analyze_And_Resolve (Thenx, Typ);
            end if;

            if Present (Else_Actions (N)) then
               Rewrite (Elsex,
                 Make_Expression_With_Actions (Sloc (Elsex),
                   Actions    => Else_Actions (N),
                   Expression => Relocate_Node (Elsex)));

               Set_Else_Actions (N, No_List);
               Analyze_And_Resolve (Elsex, Typ);
            end if;

            return;
         end if;

      --  If no actions then no expansion needed, gigi will handle it using the
      --  same approach as a C conditional expression.

      else
         return;
      end if;

      --  Fall through here for either the limited expansion, or the case of
      --  inserting actions for nonlimited types. In both these cases, we must
      --  move the SLOC of the parent If statement to the newly created one and
      --  change it to the SLOC of the expression which, after expansion, will
      --  correspond to what is being evaluated.

      if Present (Parent (N)) and then Nkind (Parent (N)) = N_If_Statement then
         Set_Sloc (New_If, Sloc (Parent (N)));
         Set_Sloc (Parent (N), Loc);
      end if;

      --  Make sure Then_Actions and Else_Actions are appropriately moved
      --  to the new if statement.

      if Present (Then_Actions (N)) then
         Insert_List_Before
           (First (Then_Statements (New_If)), Then_Actions (N));
      end if;

      if Present (Else_Actions (N)) then
         Insert_List_Before
           (First (Else_Statements (New_If)), Else_Actions (N));
      end if;

      Insert_Action (N, Decl);
      Insert_Action (N, New_If);
      Rewrite (N, New_N);
      Analyze_And_Resolve (N, Typ);
   end Expand_N_If_Expression;

   -----------------
   -- Expand_N_In --
   -----------------

   procedure Expand_N_In (N : Node_Id) is
      Loc    : constant Source_Ptr := Sloc (N);
      Restyp : constant Entity_Id  := Etype (N);
      Lop    : constant Node_Id    := Left_Opnd (N);
      Rop    : constant Node_Id    := Right_Opnd (N);
      Static : constant Boolean    := Is_OK_Static_Expression (N);

      procedure Substitute_Valid_Check;
      --  Replaces node N by Lop'Valid. This is done when we have an explicit
      --  test for the left operand being in range of its subtype.

      ----------------------------
      -- Substitute_Valid_Check --
      ----------------------------

      procedure Substitute_Valid_Check is
         function Is_OK_Object_Reference (Nod : Node_Id) return Boolean;
         --  Determine whether arbitrary node Nod denotes a source object that
         --  may safely act as prefix of attribute 'Valid.

         ----------------------------
         -- Is_OK_Object_Reference --
         ----------------------------

         function Is_OK_Object_Reference (Nod : Node_Id) return Boolean is
            Obj_Ref : Node_Id;

         begin
            --  Inspect the original operand

            Obj_Ref := Original_Node (Nod);

            --  The object reference must be a source construct, otherwise the
            --  codefix suggestion may refer to nonexistent code from a user
            --  perspective.

            if Comes_From_Source (Obj_Ref) then

               --  Recover the actual object reference. There may be more cases
               --  to consider???

               loop
                  if Nkind_In (Obj_Ref, N_Type_Conversion,
                                        N_Unchecked_Type_Conversion)
                  then
                     Obj_Ref := Expression (Obj_Ref);
                  else
                     exit;
                  end if;
               end loop;

               return Is_Object_Reference (Obj_Ref);
            end if;

            return False;
         end Is_OK_Object_Reference;

      --  Start of processing for Substitute_Valid_Check

      begin
         Rewrite (N,
           Make_Attribute_Reference (Loc,
             Prefix         => Relocate_Node (Lop),
             Attribute_Name => Name_Valid));

         Analyze_And_Resolve (N, Restyp);

         --  Emit a warning when the left-hand operand of the membership test
         --  is a source object, otherwise the use of attribute 'Valid would be
         --  illegal. The warning is not given when overflow checking is either
         --  MINIMIZED or ELIMINATED, as the danger of optimization has been
         --  eliminated above.

         if Is_OK_Object_Reference (Lop)
           and then Overflow_Check_Mode not in Minimized_Or_Eliminated
         then
            Error_Msg_N
              ("??explicit membership test may be optimized away", N);
            Error_Msg_N -- CODEFIX
              ("\??use ''Valid attribute instead", N);
         end if;
      end Substitute_Valid_Check;

      --  Local variables

      Ltyp : Entity_Id;
      Rtyp : Entity_Id;

   --  Start of processing for Expand_N_In

   begin
      --  If set membership case, expand with separate procedure

      if Present (Alternatives (N)) then
         Expand_Set_Membership (N);
         return;
      end if;

      --  Not set membership, proceed with expansion

      Ltyp := Etype (Left_Opnd  (N));
      Rtyp := Etype (Right_Opnd (N));

      --  If MINIMIZED/ELIMINATED overflow mode and type is a signed integer
      --  type, then expand with a separate procedure. Note the use of the
      --  flag No_Minimize_Eliminate to prevent infinite recursion.

      if Overflow_Check_Mode in Minimized_Or_Eliminated
        and then Is_Signed_Integer_Type (Ltyp)
        and then not No_Minimize_Eliminate (N)
      then
         Expand_Membership_Minimize_Eliminate_Overflow (N);
         return;
      end if;

      --  Check case of explicit test for an expression in range of its
      --  subtype. This is suspicious usage and we replace it with a 'Valid
      --  test and give a warning for scalar types.

      if Is_Scalar_Type (Ltyp)

        --  Only relevant for source comparisons

        and then Comes_From_Source (N)

        --  In floating-point this is a standard way to check for finite values
        --  and using 'Valid would typically be a pessimization.

        and then not Is_Floating_Point_Type (Ltyp)

        --  Don't give the message unless right operand is a type entity and
        --  the type of the left operand matches this type. Note that this
        --  eliminates the cases where MINIMIZED/ELIMINATED mode overflow
        --  checks have changed the type of the left operand.

        and then Nkind (Rop) in N_Has_Entity
        and then Ltyp = Entity (Rop)

        --  Skip this for predicated types, where such expressions are a
        --  reasonable way of testing if something meets the predicate.

        and then not Present (Predicate_Function (Ltyp))
      then
         Substitute_Valid_Check;
         return;
      end if;

      --  Do validity check on operands

      if Validity_Checks_On and Validity_Check_Operands then
         Ensure_Valid (Left_Opnd (N));
         Validity_Check_Range (Right_Opnd (N));
      end if;

      --  Case of explicit range

      if Nkind (Rop) = N_Range then
         declare
            Lo : constant Node_Id := Low_Bound (Rop);
            Hi : constant Node_Id := High_Bound (Rop);

            Lo_Orig : constant Node_Id := Original_Node (Lo);
            Hi_Orig : constant Node_Id := Original_Node (Hi);

            Lcheck : Compare_Result;
            Ucheck : Compare_Result;

            Warn1 : constant Boolean :=
                      Constant_Condition_Warnings
                        and then Comes_From_Source (N)
                        and then not In_Instance;
            --  This must be true for any of the optimization warnings, we
            --  clearly want to give them only for source with the flag on. We
            --  also skip these warnings in an instance since it may be the
            --  case that different instantiations have different ranges.

            Warn2 : constant Boolean :=
                      Warn1
                        and then Nkind (Original_Node (Rop)) = N_Range
                        and then Is_Integer_Type (Etype (Lo));
            --  For the case where only one bound warning is elided, we also
            --  insist on an explicit range and an integer type. The reason is
            --  that the use of enumeration ranges including an end point is
            --  common, as is the use of a subtype name, one of whose bounds is
            --  the same as the type of the expression.

         begin
            --  If test is explicit x'First .. x'Last, replace by valid check

            --  Could use some individual comments for this complex test ???

            if Is_Scalar_Type (Ltyp)

              --  And left operand is X'First where X matches left operand
              --  type (this eliminates cases of type mismatch, including
              --  the cases where ELIMINATED/MINIMIZED mode has changed the
              --  type of the left operand.

              and then Nkind (Lo_Orig) = N_Attribute_Reference
              and then Attribute_Name (Lo_Orig) = Name_First
              and then Nkind (Prefix (Lo_Orig)) in N_Has_Entity
              and then Entity (Prefix (Lo_Orig)) = Ltyp

              --  Same tests for right operand

              and then Nkind (Hi_Orig) = N_Attribute_Reference
              and then Attribute_Name (Hi_Orig) = Name_Last
              and then Nkind (Prefix (Hi_Orig)) in N_Has_Entity
              and then Entity (Prefix (Hi_Orig)) = Ltyp

              --  Relevant only for source cases

              and then Comes_From_Source (N)
            then
               Substitute_Valid_Check;
               goto Leave;
            end if;

            --  If bounds of type are known at compile time, and the end points
            --  are known at compile time and identical, this is another case
            --  for substituting a valid test. We only do this for discrete
            --  types, since it won't arise in practice for float types.

            if Comes_From_Source (N)
              and then Is_Discrete_Type (Ltyp)
              and then Compile_Time_Known_Value (Type_High_Bound (Ltyp))
              and then Compile_Time_Known_Value (Type_Low_Bound  (Ltyp))
              and then Compile_Time_Known_Value (Lo)
              and then Compile_Time_Known_Value (Hi)
              and then Expr_Value (Type_High_Bound (Ltyp)) = Expr_Value (Hi)
              and then Expr_Value (Type_Low_Bound  (Ltyp)) = Expr_Value (Lo)

              --  Kill warnings in instances, since they may be cases where we
              --  have a test in the generic that makes sense with some types
              --  and not with other types.

              --  Similarly, do not rewrite membership as a validity check if
              --  within the predicate function for the type.

              --  Finally, if the original bounds are type conversions, even
              --  if they have been folded into constants, there are different
              --  types involved and 'Valid is not appropriate.

            then
               if In_Instance
                 or else (Ekind (Current_Scope) = E_Function
                           and then Is_Predicate_Function (Current_Scope))
               then
                  null;

               elsif Nkind (Lo_Orig) = N_Type_Conversion
                 or else Nkind (Hi_Orig) = N_Type_Conversion
               then
                  null;

               else
                  Substitute_Valid_Check;
                  goto Leave;
               end if;
            end if;

            --  If we have an explicit range, do a bit of optimization based on
            --  range analysis (we may be able to kill one or both checks).

            Lcheck := Compile_Time_Compare (Lop, Lo, Assume_Valid => False);
            Ucheck := Compile_Time_Compare (Lop, Hi, Assume_Valid => False);

            --  If either check is known to fail, replace result by False since
            --  the other check does not matter. Preserve the static flag for
            --  legality checks, because we are constant-folding beyond RM 4.9.

            if Lcheck = LT or else Ucheck = GT then
               if Warn1 then
                  Error_Msg_N ("?c?range test optimized away", N);
                  Error_Msg_N ("\?c?value is known to be out of range", N);
               end if;

               Rewrite (N, New_Occurrence_Of (Standard_False, Loc));
               Analyze_And_Resolve (N, Restyp);
               Set_Is_Static_Expression (N, Static);
               goto Leave;

            --  If both checks are known to succeed, replace result by True,
            --  since we know we are in range.

            elsif Lcheck in Compare_GE and then Ucheck in Compare_LE then
               if Warn1 then
                  Error_Msg_N ("?c?range test optimized away", N);
                  Error_Msg_N ("\?c?value is known to be in range", N);
               end if;

               Rewrite (N, New_Occurrence_Of (Standard_True, Loc));
               Analyze_And_Resolve (N, Restyp);
               Set_Is_Static_Expression (N, Static);
               goto Leave;

            --  If lower bound check succeeds and upper bound check is not
            --  known to succeed or fail, then replace the range check with
            --  a comparison against the upper bound.

            elsif Lcheck in Compare_GE then
               if Warn2 and then not In_Instance then
                  Error_Msg_N ("??lower bound test optimized away", Lo);
                  Error_Msg_N ("\??value is known to be in range", Lo);
               end if;

               Rewrite (N,
                 Make_Op_Le (Loc,
                   Left_Opnd  => Lop,
                   Right_Opnd => High_Bound (Rop)));
               Analyze_And_Resolve (N, Restyp);
               goto Leave;

            --  If upper bound check succeeds and lower bound check is not
            --  known to succeed or fail, then replace the range check with
            --  a comparison against the lower bound.

            elsif Ucheck in Compare_LE then
               if Warn2 and then not In_Instance then
                  Error_Msg_N ("??upper bound test optimized away", Hi);
                  Error_Msg_N ("\??value is known to be in range", Hi);
               end if;

               Rewrite (N,
                 Make_Op_Ge (Loc,
                   Left_Opnd  => Lop,
                   Right_Opnd => Low_Bound (Rop)));
               Analyze_And_Resolve (N, Restyp);
               goto Leave;
            end if;

            --  We couldn't optimize away the range check, but there is one
            --  more issue. If we are checking constant conditionals, then we
            --  see if we can determine the outcome assuming everything is
            --  valid, and if so give an appropriate warning.

            if Warn1 and then not Assume_No_Invalid_Values then
               Lcheck := Compile_Time_Compare (Lop, Lo, Assume_Valid => True);
               Ucheck := Compile_Time_Compare (Lop, Hi, Assume_Valid => True);

               --  Result is out of range for valid value

               if Lcheck = LT or else Ucheck = GT then
                  Error_Msg_N
                    ("?c?value can only be in range if it is invalid", N);

               --  Result is in range for valid value

               elsif Lcheck in Compare_GE and then Ucheck in Compare_LE then
                  Error_Msg_N
                    ("?c?value can only be out of range if it is invalid", N);

               --  Lower bound check succeeds if value is valid

               elsif Warn2 and then Lcheck in Compare_GE then
                  Error_Msg_N
                    ("?c?lower bound check only fails if it is invalid", Lo);

               --  Upper bound  check succeeds if value is valid

               elsif Warn2 and then Ucheck in Compare_LE then
                  Error_Msg_N
                    ("?c?upper bound check only fails for invalid values", Hi);
               end if;
            end if;
         end;

         --  For all other cases of an explicit range, nothing to be done

         goto Leave;

      --  Here right operand is a subtype mark

      else
         declare
            Typ       : Entity_Id        := Etype (Rop);
            Is_Acc    : constant Boolean := Is_Access_Type (Typ);
            Cond      : Node_Id          := Empty;
            New_N     : Node_Id;
            Obj       : Node_Id          := Lop;
            SCIL_Node : Node_Id;

         begin
            Remove_Side_Effects (Obj);

            --  For tagged type, do tagged membership operation

            if Is_Tagged_Type (Typ) then

               --  No expansion will be performed for VM targets, as the VM
               --  back ends will handle the membership tests directly.

               if Tagged_Type_Expansion then
                  Tagged_Membership (N, SCIL_Node, New_N);
                  Rewrite (N, New_N);
                  Analyze_And_Resolve (N, Restyp, Suppress => All_Checks);

                  --  Update decoration of relocated node referenced by the
                  --  SCIL node.

                  if Generate_SCIL and then Present (SCIL_Node) then
                     Set_SCIL_Node (N, SCIL_Node);
                  end if;
               end if;

               goto Leave;

            --  If type is scalar type, rewrite as x in t'First .. t'Last.
            --  This reason we do this is that the bounds may have the wrong
            --  type if they come from the original type definition. Also this
            --  way we get all the processing above for an explicit range.

            --  Don't do this for predicated types, since in this case we
            --  want to check the predicate.

            elsif Is_Scalar_Type (Typ) then
               if No (Predicate_Function (Typ)) then
                  Rewrite (Rop,
                    Make_Range (Loc,
                      Low_Bound =>
                        Make_Attribute_Reference (Loc,
                          Attribute_Name => Name_First,
                          Prefix         => New_Occurrence_Of (Typ, Loc)),

                      High_Bound =>
                        Make_Attribute_Reference (Loc,
                          Attribute_Name => Name_Last,
                          Prefix         => New_Occurrence_Of (Typ, Loc))));
                  Analyze_And_Resolve (N, Restyp);
               end if;

               goto Leave;

            --  Ada 2005 (AI-216): Program_Error is raised when evaluating
            --  a membership test if the subtype mark denotes a constrained
            --  Unchecked_Union subtype and the expression lacks inferable
            --  discriminants.

            elsif Is_Unchecked_Union (Base_Type (Typ))
              and then Is_Constrained (Typ)
              and then not Has_Inferable_Discriminants (Lop)
            then
               Insert_Action (N,
                 Make_Raise_Program_Error (Loc,
                   Reason => PE_Unchecked_Union_Restriction));

               --  Prevent Gigi from generating incorrect code by rewriting the
               --  test as False. What is this undocumented thing about ???

               Rewrite (N, New_Occurrence_Of (Standard_False, Loc));
               goto Leave;
            end if;

            --  Here we have a non-scalar type

            if Is_Acc then
               Typ := Designated_Type (Typ);
            end if;

            if not Is_Constrained (Typ) then
               Rewrite (N, New_Occurrence_Of (Standard_True, Loc));
               Analyze_And_Resolve (N, Restyp);

            --  For the constrained array case, we have to check the subscripts
            --  for an exact match if the lengths are non-zero (the lengths
            --  must match in any case).

            elsif Is_Array_Type (Typ) then
               Check_Subscripts : declare
                  function Build_Attribute_Reference
                    (E   : Node_Id;
                     Nam : Name_Id;
                     Dim : Nat) return Node_Id;
                  --  Build attribute reference E'Nam (Dim)

                  -------------------------------
                  -- Build_Attribute_Reference --
                  -------------------------------

                  function Build_Attribute_Reference
                    (E   : Node_Id;
                     Nam : Name_Id;
                     Dim : Nat) return Node_Id
                  is
                  begin
                     return
                       Make_Attribute_Reference (Loc,
                         Prefix         => E,
                         Attribute_Name => Nam,
                         Expressions    => New_List (
                           Make_Integer_Literal (Loc, Dim)));
                  end Build_Attribute_Reference;

               --  Start of processing for Check_Subscripts

               begin
                  for J in 1 .. Number_Dimensions (Typ) loop
                     Evolve_And_Then (Cond,
                       Make_Op_Eq (Loc,
                         Left_Opnd  =>
                           Build_Attribute_Reference
                             (Duplicate_Subexpr_No_Checks (Obj),
                              Name_First, J),
                         Right_Opnd =>
                           Build_Attribute_Reference
                             (New_Occurrence_Of (Typ, Loc), Name_First, J)));

                     Evolve_And_Then (Cond,
                       Make_Op_Eq (Loc,
                         Left_Opnd  =>
                           Build_Attribute_Reference
                             (Duplicate_Subexpr_No_Checks (Obj),
                              Name_Last, J),
                         Right_Opnd =>
                           Build_Attribute_Reference
                             (New_Occurrence_Of (Typ, Loc), Name_Last, J)));
                  end loop;

                  if Is_Acc then
                     Cond :=
                       Make_Or_Else (Loc,
                         Left_Opnd  =>
                           Make_Op_Eq (Loc,
                             Left_Opnd  => Obj,
                             Right_Opnd => Make_Null (Loc)),
                         Right_Opnd => Cond);
                  end if;

                  Rewrite (N, Cond);
                  Analyze_And_Resolve (N, Restyp);
               end Check_Subscripts;

            --  These are the cases where constraint checks may be required,
            --  e.g. records with possible discriminants

            else
               --  Expand the test into a series of discriminant comparisons.
               --  The expression that is built is the negation of the one that
               --  is used for checking discriminant constraints.

               Obj := Relocate_Node (Left_Opnd (N));

               if Has_Discriminants (Typ) then
                  Cond := Make_Op_Not (Loc,
                    Right_Opnd => Build_Discriminant_Checks (Obj, Typ));

                  if Is_Acc then
                     Cond := Make_Or_Else (Loc,
                       Left_Opnd  =>
                         Make_Op_Eq (Loc,
                           Left_Opnd  => Obj,
                           Right_Opnd => Make_Null (Loc)),
                       Right_Opnd => Cond);
                  end if;

               else
                  Cond := New_Occurrence_Of (Standard_True, Loc);
               end if;

               Rewrite (N, Cond);
               Analyze_And_Resolve (N, Restyp);
            end if;

            --  Ada 2012 (AI05-0149): Handle membership tests applied to an
            --  expression of an anonymous access type. This can involve an
            --  accessibility test and a tagged type membership test in the
            --  case of tagged designated types.

            if Ada_Version >= Ada_2012
              and then Is_Acc
              and then Ekind (Ltyp) = E_Anonymous_Access_Type
            then
               declare
                  Expr_Entity : Entity_Id := Empty;
                  New_N       : Node_Id;
                  Param_Level : Node_Id;
                  Type_Level  : Node_Id;

               begin
                  if Is_Entity_Name (Lop) then
                     Expr_Entity := Param_Entity (Lop);

                     if not Present (Expr_Entity) then
                        Expr_Entity := Entity (Lop);
                     end if;
                  end if;

                  --  If a conversion of the anonymous access value to the
                  --  tested type would be illegal, then the result is False.

                  if not Valid_Conversion
                           (Lop, Rtyp, Lop, Report_Errs => False)
                  then
                     Rewrite (N, New_Occurrence_Of (Standard_False, Loc));
                     Analyze_And_Resolve (N, Restyp);

                  --  Apply an accessibility check if the access object has an
                  --  associated access level and when the level of the type is
                  --  less deep than the level of the access parameter. This
                  --  only occur for access parameters and stand-alone objects
                  --  of an anonymous access type.

                  else
                     if Present (Expr_Entity)
                       and then
                         Present
                           (Effective_Extra_Accessibility (Expr_Entity))
                       and then UI_Gt (Object_Access_Level (Lop),
                                       Type_Access_Level (Rtyp))
                     then
                        Param_Level :=
                          New_Occurrence_Of
                            (Effective_Extra_Accessibility (Expr_Entity), Loc);

                        Type_Level :=
                          Make_Integer_Literal (Loc, Type_Access_Level (Rtyp));

                        --  Return True only if the accessibility level of the
                        --  expression entity is not deeper than the level of
                        --  the tested access type.

                        Rewrite (N,
                          Make_And_Then (Loc,
                            Left_Opnd  => Relocate_Node (N),
                            Right_Opnd => Make_Op_Le (Loc,
                                            Left_Opnd  => Param_Level,
                                            Right_Opnd => Type_Level)));

                        Analyze_And_Resolve (N);
                     end if;

                     --  If the designated type is tagged, do tagged membership
                     --  operation.

                     --  *** NOTE: we have to check not null before doing the
                     --  tagged membership test (but maybe that can be done
                     --  inside Tagged_Membership?).

                     if Is_Tagged_Type (Typ) then
                        Rewrite (N,
                          Make_And_Then (Loc,
                            Left_Opnd  => Relocate_Node (N),
                            Right_Opnd =>
                              Make_Op_Ne (Loc,
                                Left_Opnd  => Obj,
                                Right_Opnd => Make_Null (Loc))));

                        --  No expansion will be performed for VM targets, as
                        --  the VM back ends will handle the membership tests
                        --  directly.

                        if Tagged_Type_Expansion then

                           --  Note that we have to pass Original_Node, because
                           --  the membership test might already have been
                           --  rewritten by earlier parts of membership test.

                           Tagged_Membership
                             (Original_Node (N), SCIL_Node, New_N);

                           --  Update decoration of relocated node referenced
                           --  by the SCIL node.

                           if Generate_SCIL and then Present (SCIL_Node) then
                              Set_SCIL_Node (New_N, SCIL_Node);
                           end if;

                           Rewrite (N,
                             Make_And_Then (Loc,
                               Left_Opnd  => Relocate_Node (N),
                               Right_Opnd => New_N));

                           Analyze_And_Resolve (N, Restyp);
                        end if;
                     end if;
                  end if;
               end;
            end if;
         end;
      end if;

   --  At this point, we have done the processing required for the basic
   --  membership test, but not yet dealt with the predicate.

   <<Leave>>

      --  If a predicate is present, then we do the predicate test, but we
      --  most certainly want to omit this if we are within the predicate
      --  function itself, since otherwise we have an infinite recursion.
      --  The check should also not be emitted when testing against a range
      --  (the check is only done when the right operand is a subtype; see
      --  RM12-4.5.2 (28.1/3-30/3)).

      Predicate_Check : declare
         function In_Range_Check return Boolean;
         --  Within an expanded range check that may raise Constraint_Error do
         --  not generate a predicate check as well. It is redundant because
         --  the context will add an explicit predicate check, and it will
         --  raise the wrong exception if it fails.

         --------------------
         -- In_Range_Check --
         --------------------

         function In_Range_Check return Boolean is
            P : Node_Id;
         begin
            P := Parent (N);
            while Present (P) loop
               if Nkind (P) = N_Raise_Constraint_Error then
                  return True;

               elsif Nkind (P) in N_Statement_Other_Than_Procedure_Call
                 or else Nkind (P) = N_Procedure_Call_Statement
                 or else Nkind (P) in N_Declaration
               then
                  return False;
               end if;

               P := Parent (P);
            end loop;

            return False;
         end In_Range_Check;

         --  Local variables

         PFunc : constant Entity_Id := Predicate_Function (Rtyp);
         R_Op  : Node_Id;

      --  Start of processing for Predicate_Check

      begin
         if Present (PFunc)
           and then Current_Scope /= PFunc
           and then Nkind (Rop) /= N_Range
         then
            if not In_Range_Check then
               R_Op := Make_Predicate_Call (Rtyp, Lop, Mem => True);
            else
               R_Op := New_Occurrence_Of (Standard_True, Loc);
            end if;

            Rewrite (N,
              Make_And_Then (Loc,
                Left_Opnd  => Relocate_Node (N),
                Right_Opnd => R_Op));

            --  Analyze new expression, mark left operand as analyzed to
            --  avoid infinite recursion adding predicate calls. Similarly,
            --  suppress further range checks on the call.

            Set_Analyzed (Left_Opnd (N));
            Analyze_And_Resolve (N, Standard_Boolean, Suppress => All_Checks);

            --  All done, skip attempt at compile time determination of result

            return;
         end if;
      end Predicate_Check;
   end Expand_N_In;

   --------------------------------
   -- Expand_N_Indexed_Component --
   --------------------------------

   procedure Expand_N_Indexed_Component (N : Node_Id) is
      Loc : constant Source_Ptr := Sloc (N);
      Typ : constant Entity_Id  := Etype (N);
      P   : constant Node_Id    := Prefix (N);
      T   : constant Entity_Id  := Etype (P);
      Atp : Entity_Id;

   begin
      --  A special optimization, if we have an indexed component that is
      --  selecting from a slice, then we can eliminate the slice, since, for
      --  example, x (i .. j)(k) is identical to x(k). The only difference is
      --  the range check required by the slice. The range check for the slice
      --  itself has already been generated. The range check for the
      --  subscripting operation is ensured by converting the subject to
      --  the subtype of the slice.

      --  This optimization not only generates better code, avoiding slice
      --  messing especially in the packed case, but more importantly bypasses
      --  some problems in handling this peculiar case, for example, the issue
      --  of dealing specially with object renamings.

      if Nkind (P) = N_Slice

        --  This optimization is disabled for CodePeer because it can transform
        --  an index-check constraint_error into a range-check constraint_error
        --  and CodePeer cares about that distinction.

        and then not CodePeer_Mode
      then
         Rewrite (N,
           Make_Indexed_Component (Loc,
             Prefix      => Prefix (P),
             Expressions => New_List (
               Convert_To
                 (Etype (First_Index (Etype (P))),
                  First (Expressions (N))))));
         Analyze_And_Resolve (N, Typ);
         return;
      end if;

      --  Ada 2005 (AI-318-02): If the prefix is a call to a build-in-place
      --  function, then additional actuals must be passed.

      if Is_Build_In_Place_Function_Call (P) then
         Make_Build_In_Place_Call_In_Anonymous_Context (P);

      --  Ada 2005 (AI-318-02): Specialization of the previous case for prefix
      --  containing build-in-place function calls whose returned object covers
      --  interface types.

      elsif Present (Unqual_BIP_Iface_Function_Call (P)) then
         Make_Build_In_Place_Iface_Call_In_Anonymous_Context (P);
      end if;

      --  If the prefix is an access type, then we unconditionally rewrite if
      --  as an explicit dereference. This simplifies processing for several
      --  cases, including packed array cases and certain cases in which checks
      --  must be generated. We used to try to do this only when it was
      --  necessary, but it cleans up the code to do it all the time.

      if Is_Access_Type (T) then
         Insert_Explicit_Dereference (P);
         Analyze_And_Resolve (P, Designated_Type (T));
         Atp := Designated_Type (T);
      else
         Atp := T;
      end if;

      --  Generate index and validity checks

      Generate_Index_Checks (N);

      if Validity_Checks_On and then Validity_Check_Subscripts then
         Apply_Subscript_Validity_Checks (N);
      end if;

      --  If selecting from an array with atomic components, and atomic sync
      --  is not suppressed for this array type, set atomic sync flag.

      if (Has_Atomic_Components (Atp)
           and then not Atomic_Synchronization_Disabled (Atp))
        or else (Is_Atomic (Typ)
                  and then not Atomic_Synchronization_Disabled (Typ))
        or else (Is_Entity_Name (P)
                  and then Has_Atomic_Components (Entity (P))
                  and then not Atomic_Synchronization_Disabled (Entity (P)))
      then
         Activate_Atomic_Synchronization (N);
      end if;

      --  All done if the prefix is not a packed array implemented specially

      if not (Is_Packed (Etype (Prefix (N)))
               and then Present (Packed_Array_Impl_Type (Etype (Prefix (N)))))
      then
         return;
      end if;

      --  For packed arrays that are not bit-packed (i.e. the case of an array
      --  with one or more index types with a non-contiguous enumeration type),
      --  we can always use the normal packed element get circuit.

      if not Is_Bit_Packed_Array (Etype (Prefix (N))) then
         Expand_Packed_Element_Reference (N);
         return;
      end if;

      --  For a reference to a component of a bit packed array, we convert it
      --  to a reference to the corresponding Packed_Array_Impl_Type. We only
      --  want to do this for simple references, and not for:

      --    Left side of assignment, or prefix of left side of assignment, or
      --    prefix of the prefix, to handle packed arrays of packed arrays,
      --      This case is handled in Exp_Ch5.Expand_N_Assignment_Statement

      --    Renaming objects in renaming associations
      --      This case is handled when a use of the renamed variable occurs

      --    Actual parameters for a subprogram call
      --      This case is handled in Exp_Ch6.Expand_Actuals

      --    The second expression in a 'Read attribute reference

      --    The prefix of an address or bit or size attribute reference

      --  The following circuit detects these exceptions. Note that we need to
      --  deal with implicit dereferences when climbing up the parent chain,
      --  with the additional difficulty that the type of parents may have yet
      --  to be resolved since prefixes are usually resolved first.

      declare
         Child : Node_Id := N;
         Parnt : Node_Id := Parent (N);

      begin
         loop
            if Nkind (Parnt) = N_Unchecked_Expression then
               null;

            elsif Nkind (Parnt) = N_Object_Renaming_Declaration then
               return;

            elsif Nkind (Parnt) in N_Subprogram_Call
              or else (Nkind (Parnt) = N_Parameter_Association
                        and then Nkind (Parent (Parnt)) in N_Subprogram_Call)
            then
               return;

            elsif Nkind (Parnt) = N_Attribute_Reference
              and then Nam_In (Attribute_Name (Parnt), Name_Address,
                                                       Name_Bit,
                                                       Name_Size)
              and then Prefix (Parnt) = Child
            then
               return;

            elsif Nkind (Parnt) = N_Assignment_Statement
              and then Name (Parnt) = Child
            then
               return;

            --  If the expression is an index of an indexed component, it must
            --  be expanded regardless of context.

            elsif Nkind (Parnt) = N_Indexed_Component
              and then Child /= Prefix (Parnt)
            then
               Expand_Packed_Element_Reference (N);
               return;

            elsif Nkind (Parent (Parnt)) = N_Assignment_Statement
              and then Name (Parent (Parnt)) = Parnt
            then
               return;

            elsif Nkind (Parnt) = N_Attribute_Reference
              and then Attribute_Name (Parnt) = Name_Read
              and then Next (First (Expressions (Parnt))) = Child
            then
               return;

            elsif Nkind (Parnt) = N_Indexed_Component
              and then Prefix (Parnt) = Child
            then
               null;

            elsif Nkind (Parnt) = N_Selected_Component
              and then Prefix (Parnt) = Child
              and then not (Present (Etype (Selector_Name (Parnt)))
                              and then
                            Is_Access_Type (Etype (Selector_Name (Parnt))))
            then
               null;

            --  If the parent is a dereference, either implicit or explicit,
            --  then the packed reference needs to be expanded.

            else
               Expand_Packed_Element_Reference (N);
               return;
            end if;

            --  Keep looking up tree for unchecked expression, or if we are the
            --  prefix of a possible assignment left side.

            Child := Parnt;
            Parnt := Parent (Child);
         end loop;
      end;
   end Expand_N_Indexed_Component;

   ---------------------
   -- Expand_N_Not_In --
   ---------------------

   --  Replace a not in b by not (a in b) so that the expansions for (a in b)
   --  can be done. This avoids needing to duplicate this expansion code.

   procedure Expand_N_Not_In (N : Node_Id) is
      Loc : constant Source_Ptr := Sloc (N);
      Typ : constant Entity_Id  := Etype (N);
      Cfs : constant Boolean    := Comes_From_Source (N);

   begin
      Rewrite (N,
        Make_Op_Not (Loc,
          Right_Opnd =>
            Make_In (Loc,
              Left_Opnd  => Left_Opnd (N),
              Right_Opnd => Right_Opnd (N))));

      --  If this is a set membership, preserve list of alternatives

      Set_Alternatives (Right_Opnd (N), Alternatives (Original_Node (N)));

      --  We want this to appear as coming from source if original does (see
      --  transformations in Expand_N_In).

      Set_Comes_From_Source (N, Cfs);
      Set_Comes_From_Source (Right_Opnd (N), Cfs);

      --  Now analyze transformed node

      Analyze_And_Resolve (N, Typ);
   end Expand_N_Not_In;

   -------------------
   -- Expand_N_Null --
   -------------------

   --  The only replacement required is for the case of a null of a type that
   --  is an access to protected subprogram, or a subtype thereof. We represent
   --  such access values as a record, and so we must replace the occurrence of
   --  null by the equivalent record (with a null address and a null pointer in
   --  it), so that the back end creates the proper value.

   procedure Expand_N_Null (N : Node_Id) is
      Loc : constant Source_Ptr := Sloc (N);
      Typ : constant Entity_Id  := Base_Type (Etype (N));
      Agg : Node_Id;

   begin
      if Is_Access_Protected_Subprogram_Type (Typ) then
         Agg :=
           Make_Aggregate (Loc,
             Expressions => New_List (
               New_Occurrence_Of (RTE (RE_Null_Address), Loc),
               Make_Null (Loc)));

         Rewrite (N, Agg);
         Analyze_And_Resolve (N, Equivalent_Type (Typ));

         --  For subsequent semantic analysis, the node must retain its type.
         --  Gigi in any case replaces this type by the corresponding record
         --  type before processing the node.

         Set_Etype (N, Typ);
      end if;

   exception
      when RE_Not_Available =>
         return;
   end Expand_N_Null;

   ---------------------
   -- Expand_N_Op_Abs --
   ---------------------

   procedure Expand_N_Op_Abs (N : Node_Id) is
      Loc  : constant Source_Ptr := Sloc (N);
      Expr : constant Node_Id    := Right_Opnd (N);

   begin
      Unary_Op_Validity_Checks (N);

      --  Check for MINIMIZED/ELIMINATED overflow mode

      if Minimized_Eliminated_Overflow_Check (N) then
         Apply_Arithmetic_Overflow_Check (N);
         return;
      end if;

      --  Deal with software overflow checking

      if Is_Signed_Integer_Type (Etype (N))
        and then Do_Overflow_Check (N)
      then
         --  The only case to worry about is when the argument is equal to the
         --  largest negative number, so what we do is to insert the check:

         --     [constraint_error when Expr = typ'Base'First]

         --  with the usual Duplicate_Subexpr use coding for expr

         Insert_Action (N,
           Make_Raise_Constraint_Error (Loc,
             Condition =>
               Make_Op_Eq (Loc,
                 Left_Opnd  => Duplicate_Subexpr (Expr),
                 Right_Opnd =>
                   Make_Attribute_Reference (Loc,
                     Prefix         =>
                       New_Occurrence_Of (Base_Type (Etype (Expr)), Loc),
                     Attribute_Name => Name_First)),
             Reason => CE_Overflow_Check_Failed));

         Set_Do_Overflow_Check (N, False);
      end if;
   end Expand_N_Op_Abs;

   ---------------------
   -- Expand_N_Op_Add --
   ---------------------

   procedure Expand_N_Op_Add (N : Node_Id) is
      Typ : constant Entity_Id := Etype (N);

   begin
      Binary_Op_Validity_Checks (N);

      --  Check for MINIMIZED/ELIMINATED overflow mode

      if Minimized_Eliminated_Overflow_Check (N) then
         Apply_Arithmetic_Overflow_Check (N);
         return;
      end if;

      --  N + 0 = 0 + N = N for integer types

      if Is_Integer_Type (Typ) then
         if Compile_Time_Known_Value (Right_Opnd (N))
           and then Expr_Value (Right_Opnd (N)) = Uint_0
         then
            Rewrite (N, Left_Opnd (N));
            return;

         elsif Compile_Time_Known_Value (Left_Opnd (N))
           and then Expr_Value (Left_Opnd (N)) = Uint_0
         then
            Rewrite (N, Right_Opnd (N));
            return;
         end if;
      end if;

      --  Arithmetic overflow checks for signed integer/fixed point types

      if Is_Signed_Integer_Type (Typ) or else Is_Fixed_Point_Type (Typ) then
         Apply_Arithmetic_Overflow_Check (N);
         return;
      end if;

      --  Overflow checks for floating-point if -gnateF mode active

      Check_Float_Op_Overflow (N);

      Expand_Nonbinary_Modular_Op (N);
   end Expand_N_Op_Add;

   ---------------------
   -- Expand_N_Op_And --
   ---------------------

   procedure Expand_N_Op_And (N : Node_Id) is
      Typ : constant Entity_Id := Etype (N);

   begin
      Binary_Op_Validity_Checks (N);

      if Is_Array_Type (Etype (N)) then
         Expand_Boolean_Operator (N);

      elsif Is_Boolean_Type (Etype (N)) then
         Adjust_Condition (Left_Opnd (N));
         Adjust_Condition (Right_Opnd (N));
         Set_Etype (N, Standard_Boolean);
         Adjust_Result_Type (N, Typ);

      elsif Is_Intrinsic_Subprogram (Entity (N)) then
         Expand_Intrinsic_Call (N, Entity (N));
      end if;

      Expand_Nonbinary_Modular_Op (N);
   end Expand_N_Op_And;

   ------------------------
   -- Expand_N_Op_Concat --
   ------------------------

   procedure Expand_N_Op_Concat (N : Node_Id) is
      Opnds : List_Id;
      --  List of operands to be concatenated

      Cnode : Node_Id;
      --  Node which is to be replaced by the result of concatenating the nodes
      --  in the list Opnds.

   begin
      --  Ensure validity of both operands

      Binary_Op_Validity_Checks (N);

      --  If we are the left operand of a concatenation higher up the tree,
      --  then do nothing for now, since we want to deal with a series of
      --  concatenations as a unit.

      if Nkind (Parent (N)) = N_Op_Concat
        and then N = Left_Opnd (Parent (N))
      then
         return;
      end if;

      --  We get here with a concatenation whose left operand may be a
      --  concatenation itself with a consistent type. We need to process
      --  these concatenation operands from left to right, which means
      --  from the deepest node in the tree to the highest node.

      Cnode := N;
      while Nkind (Left_Opnd (Cnode)) = N_Op_Concat loop
         Cnode := Left_Opnd (Cnode);
      end loop;

      --  Now Cnode is the deepest concatenation, and its parents are the
      --  concatenation nodes above, so now we process bottom up, doing the
      --  operands.

      --  The outer loop runs more than once if more than one concatenation
      --  type is involved.

      Outer : loop
         Opnds := New_List (Left_Opnd (Cnode), Right_Opnd (Cnode));
         Set_Parent (Opnds, N);

         --  The inner loop gathers concatenation operands

         Inner : while Cnode /= N
                   and then Base_Type (Etype (Cnode)) =
                            Base_Type (Etype (Parent (Cnode)))
         loop
            Cnode := Parent (Cnode);
            Append (Right_Opnd (Cnode), Opnds);
         end loop Inner;

         --  Note: The following code is a temporary workaround for N731-034
         --  and N829-028 and will be kept until the general issue of internal
         --  symbol serialization is addressed. The workaround is kept under a
         --  debug switch to avoid permiating into the general case.

         --  Wrap the node to concatenate into an expression actions node to
         --  keep it nicely packaged. This is useful in the case of an assert
         --  pragma with a concatenation where we want to be able to delete
         --  the concatenation and all its expansion stuff.

         if Debug_Flag_Dot_H then
            declare
               Cnod : constant Node_Id   := New_Copy_Tree (Cnode);
               Typ  : constant Entity_Id := Base_Type (Etype (Cnode));

            begin
               --  Note: use Rewrite rather than Replace here, so that for
               --  example Why_Not_Static can find the original concatenation
               --  node OK!

               Rewrite (Cnode,
                 Make_Expression_With_Actions (Sloc (Cnode),
                   Actions    => New_List (Make_Null_Statement (Sloc (Cnode))),
                   Expression => Cnod));

               Expand_Concatenate (Cnod, Opnds);
               Analyze_And_Resolve (Cnode, Typ);
            end;

         --  Default case

         else
            Expand_Concatenate (Cnode, Opnds);
         end if;

         exit Outer when Cnode = N;
         Cnode := Parent (Cnode);
      end loop Outer;
   end Expand_N_Op_Concat;

   ------------------------
   -- Expand_N_Op_Divide --
   ------------------------

   procedure Expand_N_Op_Divide (N : Node_Id) is
      Loc   : constant Source_Ptr := Sloc (N);
      Lopnd : constant Node_Id    := Left_Opnd (N);
      Ropnd : constant Node_Id    := Right_Opnd (N);
      Ltyp  : constant Entity_Id  := Etype (Lopnd);
      Rtyp  : constant Entity_Id  := Etype (Ropnd);
      Typ   : Entity_Id           := Etype (N);
      Rknow : constant Boolean    := Is_Integer_Type (Typ)
                                       and then
                                         Compile_Time_Known_Value (Ropnd);
      Rval  : Uint;

   begin
      Binary_Op_Validity_Checks (N);

      --  Check for MINIMIZED/ELIMINATED overflow mode

      if Minimized_Eliminated_Overflow_Check (N) then
         Apply_Arithmetic_Overflow_Check (N);
         return;
      end if;

      --  Otherwise proceed with expansion of division

      if Rknow then
         Rval := Expr_Value (Ropnd);
      end if;

      --  N / 1 = N for integer types

      if Rknow and then Rval = Uint_1 then
         Rewrite (N, Lopnd);
         return;
      end if;

      --  Convert x / 2 ** y to Shift_Right (x, y). Note that the fact that
      --  Is_Power_Of_2_For_Shift is set means that we know that our left
      --  operand is an unsigned integer, as required for this to work.

      if Nkind (Ropnd) = N_Op_Expon
        and then Is_Power_Of_2_For_Shift (Ropnd)

      --  We cannot do this transformation in configurable run time mode if we
      --  have 64-bit integers and long shifts are not available.

        and then (Esize (Ltyp) <= 32 or else Support_Long_Shifts_On_Target)
      then
         Rewrite (N,
           Make_Op_Shift_Right (Loc,
             Left_Opnd  => Lopnd,
             Right_Opnd =>
               Convert_To (Standard_Natural, Right_Opnd (Ropnd))));
         Analyze_And_Resolve (N, Typ);
         return;
      end if;

      --  Do required fixup of universal fixed operation

      if Typ = Universal_Fixed then
         Fixup_Universal_Fixed_Operation (N);
         Typ := Etype (N);
      end if;

      --  Divisions with fixed-point results

      if Is_Fixed_Point_Type (Typ) then

         --  No special processing if Treat_Fixed_As_Integer is set, since
         --  from a semantic point of view such operations are simply integer
         --  operations and will be treated that way.

         if not Treat_Fixed_As_Integer (N) then
            if Is_Integer_Type (Rtyp) then
               Expand_Divide_Fixed_By_Integer_Giving_Fixed (N);
            else
               Expand_Divide_Fixed_By_Fixed_Giving_Fixed (N);
            end if;
         end if;

         --  Deal with divide-by-zero check if back end cannot handle them
         --  and the flag is set indicating that we need such a check. Note
         --  that we don't need to bother here with the case of mixed-mode
         --  (Right operand an integer type), since these will be rewritten
         --  with conversions to a divide with a fixed-point right operand.

         if Nkind (N) = N_Op_Divide
           and then Do_Division_Check (N)
           and then not Backend_Divide_Checks_On_Target
           and then not Is_Integer_Type (Rtyp)
         then
            Set_Do_Division_Check (N, False);
            Insert_Action (N,
              Make_Raise_Constraint_Error (Loc,
                Condition =>
                  Make_Op_Eq (Loc,
                    Left_Opnd  => Duplicate_Subexpr_Move_Checks (Ropnd),
                    Right_Opnd => Make_Real_Literal (Loc, Ureal_0)),
                  Reason  => CE_Divide_By_Zero));
         end if;

      --  Other cases of division of fixed-point operands. Again we exclude the
      --  case where Treat_Fixed_As_Integer is set.

      elsif (Is_Fixed_Point_Type (Ltyp) or else Is_Fixed_Point_Type (Rtyp))
        and then not Treat_Fixed_As_Integer (N)
      then
         if Is_Integer_Type (Typ) then
            Expand_Divide_Fixed_By_Fixed_Giving_Integer (N);
         else
            pragma Assert (Is_Floating_Point_Type (Typ));
            Expand_Divide_Fixed_By_Fixed_Giving_Float (N);
         end if;

      --  Mixed-mode operations can appear in a non-static universal context,
      --  in which case the integer argument must be converted explicitly.

      elsif Typ = Universal_Real and then Is_Integer_Type (Rtyp) then
         Rewrite (Ropnd,
           Convert_To (Universal_Real, Relocate_Node (Ropnd)));

         Analyze_And_Resolve (Ropnd, Universal_Real);

      elsif Typ = Universal_Real and then Is_Integer_Type (Ltyp) then
         Rewrite (Lopnd,
           Convert_To (Universal_Real, Relocate_Node (Lopnd)));

         Analyze_And_Resolve (Lopnd, Universal_Real);

      --  Non-fixed point cases, do integer zero divide and overflow checks

      elsif Is_Integer_Type (Typ) then
         Apply_Divide_Checks (N);
      end if;

      --  Overflow checks for floating-point if -gnateF mode active

      Check_Float_Op_Overflow (N);

      Expand_Nonbinary_Modular_Op (N);
   end Expand_N_Op_Divide;

   --------------------
   -- Expand_N_Op_Eq --
   --------------------

   procedure Expand_N_Op_Eq (N : Node_Id) is
      Loc    : constant Source_Ptr := Sloc (N);
      Typ    : constant Entity_Id  := Etype (N);
      Lhs    : constant Node_Id    := Left_Opnd (N);
      Rhs    : constant Node_Id    := Right_Opnd (N);
      Bodies : constant List_Id    := New_List;
      A_Typ  : constant Entity_Id  := Etype (Lhs);

      procedure Build_Equality_Call (Eq : Entity_Id);
      --  If a constructed equality exists for the type or for its parent,
      --  build and analyze call, adding conversions if the operation is
      --  inherited.

      function Is_Equality (Subp : Entity_Id;
                            Typ  : Entity_Id := Empty) return Boolean;
      --  Determine whether arbitrary Entity_Id denotes a function with the
      --  right name and profile for an equality op, specifically for the
      --  base type Typ if Typ is nonempty.

      function Find_Equality (Prims : Elist_Id) return Entity_Id;
      --  Find a primitive equality function within primitive operation list
      --  Prims.

      function User_Defined_Primitive_Equality_Op
        (Typ : Entity_Id) return Entity_Id;
      --  Find a user-defined primitive equality function for a given untagged
      --  record type, ignoring visibility. Return Empty if no such op found.

      function Has_Unconstrained_UU_Component (Typ : Entity_Id) return Boolean;
      --  Determines whether a type has a subcomponent of an unconstrained
      --  Unchecked_Union subtype. Typ is a record type.

      -------------------------
      -- Build_Equality_Call --
      -------------------------

      procedure Build_Equality_Call (Eq : Entity_Id) is
         Op_Type : constant Entity_Id := Etype (First_Formal (Eq));
         L_Exp   : Node_Id            := Relocate_Node (Lhs);
         R_Exp   : Node_Id            := Relocate_Node (Rhs);

      begin
         --  Adjust operands if necessary to comparison type

         if Base_Type (Op_Type) /= Base_Type (A_Typ)
           and then not Is_Class_Wide_Type (A_Typ)
         then
            L_Exp := OK_Convert_To (Op_Type, L_Exp);
            R_Exp := OK_Convert_To (Op_Type, R_Exp);
         end if;

         --  If we have an Unchecked_Union, we need to add the inferred
         --  discriminant values as actuals in the function call. At this
         --  point, the expansion has determined that both operands have
         --  inferable discriminants.

         if Is_Unchecked_Union (Op_Type) then
            declare
               Lhs_Type : constant Node_Id := Etype (L_Exp);
               Rhs_Type : constant Node_Id := Etype (R_Exp);

               Lhs_Discr_Vals : Elist_Id;
               --  List of inferred discriminant values for left operand.

               Rhs_Discr_Vals : Elist_Id;
               --  List of inferred discriminant values for right operand.

               Discr : Entity_Id;

            begin
               Lhs_Discr_Vals := New_Elmt_List;
               Rhs_Discr_Vals := New_Elmt_List;

               --  Per-object constrained selected components require special
               --  attention. If the enclosing scope of the component is an
               --  Unchecked_Union, we cannot reference its discriminants
               --  directly. This is why we use the extra parameters of the
               --  equality function of the enclosing Unchecked_Union.

               --  type UU_Type (Discr : Integer := 0) is
               --     . . .
               --  end record;
               --  pragma Unchecked_Union (UU_Type);

               --  1. Unchecked_Union enclosing record:

               --     type Enclosing_UU_Type (Discr : Integer := 0) is record
               --        . . .
               --        Comp : UU_Type (Discr);
               --        . . .
               --     end Enclosing_UU_Type;
               --     pragma Unchecked_Union (Enclosing_UU_Type);

               --     Obj1 : Enclosing_UU_Type;
               --     Obj2 : Enclosing_UU_Type (1);

               --     [. . .] Obj1 = Obj2 [. . .]

               --     Generated code:

               --     if not (uu_typeEQ (obj1.comp, obj2.comp, a, b)) then

               --  A and B are the formal parameters of the equality function
               --  of Enclosing_UU_Type. The function always has two extra
               --  formals to capture the inferred discriminant values for
               --  each discriminant of the type.

               --  2. Non-Unchecked_Union enclosing record:

               --     type
               --       Enclosing_Non_UU_Type (Discr : Integer := 0)
               --     is record
               --        . . .
               --        Comp : UU_Type (Discr);
               --        . . .
               --     end Enclosing_Non_UU_Type;

               --     Obj1 : Enclosing_Non_UU_Type;
               --     Obj2 : Enclosing_Non_UU_Type (1);

               --     ... Obj1 = Obj2 ...

               --     Generated code:

               --     if not (uu_typeEQ (obj1.comp, obj2.comp,
               --                        obj1.discr, obj2.discr)) then

               --  In this case we can directly reference the discriminants of
               --  the enclosing record.

               --  Process left operand of equality

               if Nkind (Lhs) = N_Selected_Component
                 and then
                   Has_Per_Object_Constraint (Entity (Selector_Name (Lhs)))
               then
                  --  If enclosing record is an Unchecked_Union, use formals
                  --  corresponding to each discriminant. The name of the
                  --  formal is that of the discriminant, with added suffix,
                  --  see Exp_Ch3.Build_Record_Equality for details.

                  if Is_Unchecked_Union (Scope (Entity (Selector_Name (Lhs))))
                  then
                     Discr :=
                       First_Discriminant
                         (Scope (Entity (Selector_Name (Lhs))));
                     while Present (Discr) loop
                        Append_Elmt
                          (Make_Identifier (Loc,
                             Chars => New_External_Name (Chars (Discr), 'A')),
                           To => Lhs_Discr_Vals);
                        Next_Discriminant (Discr);
                     end loop;

                  --  If enclosing record is of a non-Unchecked_Union type, it
                  --  is possible to reference its discriminants directly.

                  else
                     Discr := First_Discriminant (Lhs_Type);
                     while Present (Discr) loop
                        Append_Elmt
                          (Make_Selected_Component (Loc,
                             Prefix        => Prefix (Lhs),
                             Selector_Name =>
                               New_Copy
                                 (Get_Discriminant_Value (Discr,
                                     Lhs_Type,
                                     Stored_Constraint (Lhs_Type)))),
                           To => Lhs_Discr_Vals);
                        Next_Discriminant (Discr);
                     end loop;
                  end if;

               --  Otherwise operand is on object with a constrained type.
               --  Infer the discriminant values from the constraint.

               else
                  Discr := First_Discriminant (Lhs_Type);
                  while Present (Discr) loop
                     Append_Elmt
                       (New_Copy
                          (Get_Discriminant_Value (Discr,
                             Lhs_Type,
                             Stored_Constraint (Lhs_Type))),
                        To => Lhs_Discr_Vals);
                     Next_Discriminant (Discr);
                  end loop;
               end if;

               --  Similar processing for right operand of equality

               if Nkind (Rhs) = N_Selected_Component
                 and then
                   Has_Per_Object_Constraint (Entity (Selector_Name (Rhs)))
               then
                  if Is_Unchecked_Union
                       (Scope (Entity (Selector_Name (Rhs))))
                  then
                     Discr :=
                       First_Discriminant
                         (Scope (Entity (Selector_Name (Rhs))));
                     while Present (Discr) loop
                        Append_Elmt
                          (Make_Identifier (Loc,
                             Chars => New_External_Name (Chars (Discr), 'B')),
                           To => Rhs_Discr_Vals);
                        Next_Discriminant (Discr);
                     end loop;

                  else
                     Discr := First_Discriminant (Rhs_Type);
                     while Present (Discr) loop
                        Append_Elmt
                          (Make_Selected_Component (Loc,
                             Prefix        => Prefix (Rhs),
                             Selector_Name =>
                               New_Copy (Get_Discriminant_Value
                                           (Discr,
                                            Rhs_Type,
                                            Stored_Constraint (Rhs_Type)))),
                           To => Rhs_Discr_Vals);
                        Next_Discriminant (Discr);
                     end loop;
                  end if;

               else
                  Discr := First_Discriminant (Rhs_Type);
                  while Present (Discr) loop
                     Append_Elmt
                       (New_Copy (Get_Discriminant_Value
                                    (Discr,
                                     Rhs_Type,
                                     Stored_Constraint (Rhs_Type))),
                        To => Rhs_Discr_Vals);
                     Next_Discriminant (Discr);
                  end loop;
               end if;

               --  Now merge the list of discriminant values so that values
               --  of corresponding discriminants are adjacent.

               declare
                  Params : List_Id;
                  L_Elmt : Elmt_Id;
                  R_Elmt : Elmt_Id;

               begin
                  Params := New_List (L_Exp, R_Exp);
                  L_Elmt := First_Elmt (Lhs_Discr_Vals);
                  R_Elmt := First_Elmt (Rhs_Discr_Vals);
                  while Present (L_Elmt) loop
                     Append_To (Params, Node (L_Elmt));
                     Append_To (Params, Node (R_Elmt));
                     Next_Elmt (L_Elmt);
                     Next_Elmt (R_Elmt);
                  end loop;

                  Rewrite (N,
                    Make_Function_Call (Loc,
                      Name                   => New_Occurrence_Of (Eq, Loc),
                      Parameter_Associations => Params));
               end;
            end;

         --  Normal case, not an unchecked union

         else
            Rewrite (N,
              Make_Function_Call (Loc,
                Name                   => New_Occurrence_Of (Eq, Loc),
                Parameter_Associations => New_List (L_Exp, R_Exp)));
         end if;

         Analyze_And_Resolve (N, Standard_Boolean, Suppress => All_Checks);
      end Build_Equality_Call;

      -----------------
      -- Is_Equality --
      -----------------

      function Is_Equality (Subp : Entity_Id;
                            Typ  : Entity_Id := Empty) return Boolean is
         Formal_1 : Entity_Id;
         Formal_2 : Entity_Id;
      begin
         --  The equality function carries name "=", returns Boolean, and has
         --  exactly two formal parameters of an identical type.

         if Ekind (Subp) = E_Function
           and then Chars (Subp) = Name_Op_Eq
           and then Base_Type (Etype (Subp)) = Standard_Boolean
         then
            Formal_1 := First_Formal (Subp);
            Formal_2 := Empty;

            if Present (Formal_1) then
               Formal_2 := Next_Formal (Formal_1);
            end if;

            return
              Present (Formal_1)
                and then Present (Formal_2)
                and then No (Next_Formal (Formal_2))
                and then Base_Type (Etype (Formal_1)) =
                         Base_Type (Etype (Formal_2))
                and then
                  (not Present (Typ)
                    or else Implementation_Base_Type (Etype (Formal_1)) = Typ);
         end if;

         return False;
      end Is_Equality;

      -------------------
      -- Find_Equality --
      -------------------

      function Find_Equality (Prims : Elist_Id) return Entity_Id is
         function Find_Aliased_Equality (Prim : Entity_Id) return Entity_Id;
         --  Find an equality in a possible alias chain starting from primitive
         --  operation Prim.

         ---------------------------
         -- Find_Aliased_Equality --
         ---------------------------

         function Find_Aliased_Equality (Prim : Entity_Id) return Entity_Id is
            Candid : Entity_Id;

         begin
            --  Inspect each candidate in the alias chain, checking whether it
            --  denotes an equality.

            Candid := Prim;
            while Present (Candid) loop
               if Is_Equality (Candid) then
                  return Candid;
               end if;

               Candid := Alias (Candid);
            end loop;

            return Empty;
         end Find_Aliased_Equality;

         --  Local variables

         Eq_Prim   : Entity_Id;
         Prim_Elmt : Elmt_Id;

      --  Start of processing for Find_Equality

      begin
         --  Assume that the tagged type lacks an equality

         Eq_Prim := Empty;

         --  Inspect the list of primitives looking for a suitable equality
         --  within a possible chain of aliases.

         Prim_Elmt := First_Elmt (Prims);
         while Present (Prim_Elmt) and then No (Eq_Prim) loop
            Eq_Prim := Find_Aliased_Equality (Node (Prim_Elmt));

            Next_Elmt (Prim_Elmt);
         end loop;

         --  A tagged type should always have an equality

         pragma Assert (Present (Eq_Prim));

         return Eq_Prim;
      end Find_Equality;

      ----------------------------------------
      -- User_Defined_Primitive_Equality_Op --
      ----------------------------------------

      function User_Defined_Primitive_Equality_Op
        (Typ : Entity_Id) return Entity_Id
      is
         Enclosing_Scope : constant Node_Id := Scope (Typ);
         E : Entity_Id;
      begin
         --  Prune this search by somehow not looking at decls that precede
         --  the declaration of the first view of Typ (which might be a partial
         --  view)???

         for Private_Entities in Boolean loop
            if Private_Entities then
               if Ekind (Enclosing_Scope) /= E_Package then
                  exit;
               end if;
               E := First_Private_Entity (Enclosing_Scope);

            else
               E := First_Entity (Enclosing_Scope);
            end if;

            while Present (E) loop
               if Is_Equality (E, Typ) then
                  return E;
               end if;
               E := Next_Entity (E);
            end loop;
         end loop;

         if Is_Derived_Type (Typ) then
            return User_Defined_Primitive_Equality_Op
                     (Implementation_Base_Type (Etype (Typ)));
         end if;

         return Empty;
      end User_Defined_Primitive_Equality_Op;

      ------------------------------------
      -- Has_Unconstrained_UU_Component --
      ------------------------------------

      function Has_Unconstrained_UU_Component
        (Typ : Entity_Id) return Boolean
      is
         Tdef  : constant Node_Id :=
                   Type_Definition (Declaration_Node (Base_Type (Typ)));
         Clist : Node_Id;
         Vpart : Node_Id;

         function Component_Is_Unconstrained_UU
           (Comp : Node_Id) return Boolean;
         --  Determines whether the subtype of the component is an
         --  unconstrained Unchecked_Union.

         function Variant_Is_Unconstrained_UU
           (Variant : Node_Id) return Boolean;
         --  Determines whether a component of the variant has an unconstrained
         --  Unchecked_Union subtype.

         -----------------------------------
         -- Component_Is_Unconstrained_UU --
         -----------------------------------

         function Component_Is_Unconstrained_UU
           (Comp : Node_Id) return Boolean
         is
         begin
            if Nkind (Comp) /= N_Component_Declaration then
               return False;
            end if;

            declare
               Sindic : constant Node_Id :=
                          Subtype_Indication (Component_Definition (Comp));

            begin
               --  Unconstrained nominal type. In the case of a constraint
               --  present, the node kind would have been N_Subtype_Indication.

               if Nkind (Sindic) = N_Identifier then
                  return Is_Unchecked_Union (Base_Type (Etype (Sindic)));
               end if;

               return False;
            end;
         end Component_Is_Unconstrained_UU;

         ---------------------------------
         -- Variant_Is_Unconstrained_UU --
         ---------------------------------

         function Variant_Is_Unconstrained_UU
           (Variant : Node_Id) return Boolean
         is
            Clist : constant Node_Id := Component_List (Variant);

         begin
            if Is_Empty_List (Component_Items (Clist)) then
               return False;
            end if;

            --  We only need to test one component

            declare
               Comp : Node_Id := First (Component_Items (Clist));

            begin
               while Present (Comp) loop
                  if Component_Is_Unconstrained_UU (Comp) then
                     return True;
                  end if;

                  Next (Comp);
               end loop;
            end;

            --  None of the components withing the variant were of
            --  unconstrained Unchecked_Union type.

            return False;
         end Variant_Is_Unconstrained_UU;

      --  Start of processing for Has_Unconstrained_UU_Component

      begin
         if Null_Present (Tdef) then
            return False;
         end if;

         Clist := Component_List (Tdef);
         Vpart := Variant_Part (Clist);

         --  Inspect available components

         if Present (Component_Items (Clist)) then
            declare
               Comp : Node_Id := First (Component_Items (Clist));

            begin
               while Present (Comp) loop

                  --  One component is sufficient

                  if Component_Is_Unconstrained_UU (Comp) then
                     return True;
                  end if;

                  Next (Comp);
               end loop;
            end;
         end if;

         --  Inspect available components withing variants

         if Present (Vpart) then
            declare
               Variant : Node_Id := First (Variants (Vpart));

            begin
               while Present (Variant) loop

                  --  One component within a variant is sufficient

                  if Variant_Is_Unconstrained_UU (Variant) then
                     return True;
                  end if;

                  Next (Variant);
               end loop;
            end;
         end if;

         --  Neither the available components, nor the components inside the
         --  variant parts were of an unconstrained Unchecked_Union subtype.

         return False;
      end Has_Unconstrained_UU_Component;

      --  Local variables

      Typl : Entity_Id;

   --  Start of processing for Expand_N_Op_Eq

   begin
      Binary_Op_Validity_Checks (N);

      --  Deal with private types

      Typl := A_Typ;

      if Ekind (Typl) = E_Private_Type then
         Typl := Underlying_Type (Typl);

      elsif Ekind (Typl) = E_Private_Subtype then
         Typl := Underlying_Type (Base_Type (Typl));
      end if;

      --  It may happen in error situations that the underlying type is not
      --  set. The error will be detected later, here we just defend the
      --  expander code.

      if No (Typl) then
         return;
      end if;

      --  Now get the implementation base type (note that plain Base_Type here
      --  might lead us back to the private type, which is not what we want!)

      Typl := Implementation_Base_Type (Typl);

      --  Equality between variant records results in a call to a routine
      --  that has conditional tests of the discriminant value(s), and hence
      --  violates the No_Implicit_Conditionals restriction.

      if Has_Variant_Part (Typl) then
         declare
            Msg : Boolean;

         begin
            Check_Restriction (Msg, No_Implicit_Conditionals, N);

            if Msg then
               Error_Msg_N
                 ("\comparison of variant records tests discriminants", N);
               return;
            end if;
         end;
      end if;

      --  Deal with overflow checks in MINIMIZED/ELIMINATED mode and if that
      --  means we no longer have a comparison operation, we are all done.

      Expand_Compare_Minimize_Eliminate_Overflow (N);

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

      --  Boolean types (requiring handling of non-standard case)

      if Is_Boolean_Type (Typl) then
         Adjust_Condition (Left_Opnd (N));
         Adjust_Condition (Right_Opnd (N));
         Set_Etype (N, Standard_Boolean);
         Adjust_Result_Type (N, Typ);

      --  Array types

      elsif Is_Array_Type (Typl) then

         --  If we are doing full validity checking, and it is possible for the
         --  array elements to be invalid then expand out array comparisons to
         --  make sure that we check the array elements.

         if Validity_Check_Operands
           and then not Is_Known_Valid (Component_Type (Typl))
         then
            declare
               Save_Force_Validity_Checks : constant Boolean :=
                                              Force_Validity_Checks;
            begin
               Force_Validity_Checks := True;
               Rewrite (N,
                 Expand_Array_Equality
                  (N,
                   Relocate_Node (Lhs),
                   Relocate_Node (Rhs),
                   Bodies,
                   Typl));
               Insert_Actions (N, Bodies);
               Analyze_And_Resolve (N, Standard_Boolean);
               Force_Validity_Checks := Save_Force_Validity_Checks;
            end;

         --  Packed case where both operands are known aligned

         elsif Is_Bit_Packed_Array (Typl)
           and then not Is_Possibly_Unaligned_Object (Lhs)
           and then not Is_Possibly_Unaligned_Object (Rhs)
         then
            Expand_Packed_Eq (N);

         --  Where the component type is elementary we can use a block bit
         --  comparison (if supported on the target) exception in the case
         --  of floating-point (negative zero issues require element by
         --  element comparison), and atomic/VFA types (where we must be sure
         --  to load elements independently) and possibly unaligned arrays.

         elsif Is_Elementary_Type (Component_Type (Typl))
           and then not Is_Floating_Point_Type (Component_Type (Typl))
           and then not Is_Atomic_Or_VFA (Component_Type (Typl))
           and then not Is_Possibly_Unaligned_Object (Lhs)
           and then not Is_Possibly_Unaligned_Slice (Lhs)
           and then not Is_Possibly_Unaligned_Object (Rhs)
           and then not Is_Possibly_Unaligned_Slice (Rhs)
           and then Support_Composite_Compare_On_Target
         then
            null;

         --  For composite and floating-point cases, expand equality loop to
         --  make sure of using proper comparisons for tagged types, and
         --  correctly handling the floating-point case.

         else
            Rewrite (N,
              Expand_Array_Equality
                (N,
                 Relocate_Node (Lhs),
                 Relocate_Node (Rhs),
                 Bodies,
                 Typl));
            Insert_Actions      (N, Bodies,           Suppress => All_Checks);
            Analyze_And_Resolve (N, Standard_Boolean, Suppress => All_Checks);
         end if;

      --  Record Types

      elsif Is_Record_Type (Typl) then

         --  For tagged types, use the primitive "="

         if Is_Tagged_Type (Typl) then

            --  No need to do anything else compiling under restriction
            --  No_Dispatching_Calls. During the semantic analysis we
            --  already notified such violation.

            if Restriction_Active (No_Dispatching_Calls) then
               return;
            end if;

            --  If this is an untagged private type completed with a derivation
            --  of an untagged private type whose full view is a tagged type,
            --  we use the primitive operations of the private type (since it
            --  does not have a full view, and also because its equality
            --  primitive may have been overridden in its untagged full view).

            if Inherits_From_Tagged_Full_View (A_Typ) then
               Build_Equality_Call
                 (Find_Equality (Collect_Primitive_Operations (A_Typ)));

            --  Find the type's predefined equality or an overriding
            --  user-defined equality. The reason for not simply calling
            --  Find_Prim_Op here is that there may be a user-defined
            --  overloaded equality op that precedes the equality that we
            --  want, so we have to explicitly search (e.g., there could be
            --  an equality with two different parameter types).

            else
               if Is_Class_Wide_Type (Typl) then
                  Typl := Find_Specific_Type (Typl);
               end if;

               Build_Equality_Call
                 (Find_Equality (Primitive_Operations (Typl)));
            end if;

         --  See AI12-0101 (which only removes a legality rule) and then
         --  AI05-0123 (which then applies in the previously illegal case).
         --  AI12-0101 is a binding interpretation.

         elsif Ada_Version >= Ada_2012
           and then Present (User_Defined_Primitive_Equality_Op (Typl))
         then
            Build_Equality_Call (User_Defined_Primitive_Equality_Op (Typl));

         --  Ada 2005 (AI-216): Program_Error is raised when evaluating the
         --  predefined equality operator for a type which has a subcomponent
         --  of an Unchecked_Union type whose nominal subtype is unconstrained.

         elsif Has_Unconstrained_UU_Component (Typl) then
            Insert_Action (N,
              Make_Raise_Program_Error (Loc,
                Reason => PE_Unchecked_Union_Restriction));

            --  Prevent Gigi from generating incorrect code by rewriting the
            --  equality as a standard False. (is this documented somewhere???)

            Rewrite (N,
              New_Occurrence_Of (Standard_False, Loc));

         elsif Is_Unchecked_Union (Typl) then

            --  If we can infer the discriminants of the operands, we make a
            --  call to the TSS equality function.

            if Has_Inferable_Discriminants (Lhs)
                 and then
               Has_Inferable_Discriminants (Rhs)
            then
               Build_Equality_Call
                 (TSS (Root_Type (Typl), TSS_Composite_Equality));

            else
               --  Ada 2005 (AI-216): Program_Error is raised when evaluating
               --  the predefined equality operator for an Unchecked_Union type
               --  if either of the operands lack inferable discriminants.

               Insert_Action (N,
                 Make_Raise_Program_Error (Loc,
                   Reason => PE_Unchecked_Union_Restriction));

               --  Emit a warning on source equalities only, otherwise the
               --  message may appear out of place due to internal use. The
               --  warning is unconditional because it is required by the
               --  language.

               if Comes_From_Source (N) then
                  Error_Msg_N
                    ("Unchecked_Union discriminants cannot be determined??",
                     N);
                  Error_Msg_N
                    ("\Program_Error will be raised for equality operation??",
                     N);
               end if;

               --  Prevent Gigi from generating incorrect code by rewriting
               --  the equality as a standard False (documented where???).

               Rewrite (N,
                 New_Occurrence_Of (Standard_False, Loc));
            end if;

         --  If a type support function is present (for complex cases), use it

         elsif Present (TSS (Root_Type (Typl), TSS_Composite_Equality)) then
            Build_Equality_Call
              (TSS (Root_Type (Typl), TSS_Composite_Equality));

         --  When comparing two Bounded_Strings, use the primitive equality of
         --  the root Super_String type.

         elsif Is_Bounded_String (Typl) then
            Build_Equality_Call
              (Find_Equality
                (Collect_Primitive_Operations (Root_Type (Typl))));

         --  Otherwise expand the component by component equality. Note that
         --  we never use block-bit comparisons for records, because of the
         --  problems with gaps. The back end will often be able to recombine
         --  the separate comparisons that we generate here.

         else
            Remove_Side_Effects (Lhs);
            Remove_Side_Effects (Rhs);
            Rewrite (N,
              Expand_Record_Equality (N, Typl, Lhs, Rhs, Bodies));

            Insert_Actions      (N, Bodies,           Suppress => All_Checks);
            Analyze_And_Resolve (N, Standard_Boolean, Suppress => All_Checks);
         end if;

      --  If unnesting, handle elementary types whose Equivalent_Types are
      --  records because there may be padding or undefined fields.

      elsif Unnest_Subprogram_Mode
        and then Ekind_In (Typl, E_Class_Wide_Type,
                                 E_Class_Wide_Subtype,
                                 E_Access_Subprogram_Type,
                                 E_Access_Protected_Subprogram_Type,
                                 E_Anonymous_Access_Protected_Subprogram_Type,
                                 E_Access_Subprogram_Type,
                                 E_Exception_Type)
        and then Present (Equivalent_Type (Typl))
        and then Is_Record_Type (Equivalent_Type (Typl))
      then
         Typl := Equivalent_Type (Typl);
         Remove_Side_Effects (Lhs);
         Remove_Side_Effects (Rhs);
         Rewrite (N,
           Expand_Record_Equality (N, Typl,
             Unchecked_Convert_To (Typl, Lhs),
             Unchecked_Convert_To (Typl, Rhs),
             Bodies));

         Insert_Actions      (N, Bodies,           Suppress => All_Checks);
         Analyze_And_Resolve (N, Standard_Boolean, Suppress => All_Checks);
      end if;

      --  Test if result is known at compile time

      Rewrite_Comparison (N);

      --  Special optimization of length comparison

      Optimize_Length_Comparison (N);

      --  One more special case: if we have a comparison of X'Result = expr
      --  in floating-point, then if not already there, change expr to be
      --  f'Machine (expr) to eliminate surprise from extra precision.

      if Is_Floating_Point_Type (Typl)
        and then Nkind (Original_Node (Lhs)) = N_Attribute_Reference
        and then Attribute_Name (Original_Node (Lhs)) = Name_Result
      then
         --  Stick in the Typ'Machine call if not already there

         if Nkind (Rhs) /= N_Attribute_Reference
           or else Attribute_Name (Rhs) /= Name_Machine
         then
            Rewrite (Rhs,
              Make_Attribute_Reference (Loc,
                Prefix         => New_Occurrence_Of (Typl, Loc),
                Attribute_Name => Name_Machine,
                Expressions    => New_List (Relocate_Node (Rhs))));
            Analyze_And_Resolve (Rhs, Typl);
         end if;
      end if;
   end Expand_N_Op_Eq;

   -----------------------
   -- Expand_N_Op_Expon --
   -----------------------

   procedure Expand_N_Op_Expon (N : Node_Id) is
      Loc   : constant Source_Ptr := Sloc (N);
      Ovflo : constant Boolean    := Do_Overflow_Check (N);
      Typ   : constant Entity_Id  := Etype (N);
      Rtyp  : constant Entity_Id  := Root_Type (Typ);

      Bastyp : Entity_Id;

      function Wrap_MA (Exp : Node_Id) return Node_Id;
      --  Given an expression Exp, if the root type is Float or Long_Float,
      --  then wrap the expression in a call of Bastyp'Machine, to stop any
      --  extra precision. This is done to ensure that X**A = X**B when A is
      --  a static constant and B is a variable with the same value. For any
      --  other type, the node Exp is returned unchanged.

      -------------
      -- Wrap_MA --
      -------------

      function Wrap_MA (Exp : Node_Id) return Node_Id is
         Loc : constant Source_Ptr := Sloc (Exp);

      begin
         if Rtyp = Standard_Float or else Rtyp = Standard_Long_Float then
            return
              Make_Attribute_Reference (Loc,
                Attribute_Name => Name_Machine,
                Prefix         => New_Occurrence_Of (Bastyp, Loc),
                Expressions    => New_List (Relocate_Node (Exp)));
         else
            return Exp;
         end if;
      end Wrap_MA;

      --  Local variables

      Base   : Node_Id;
      Ent    : Entity_Id;
      Etyp   : Entity_Id;
      Exp    : Node_Id;
      Exptyp : Entity_Id;
      Expv   : Uint;
      Rent   : RE_Id;
      Temp   : Node_Id;
      Xnode  : Node_Id;

   --  Start of processing for Expand_N_Op_Expon

   begin
      Binary_Op_Validity_Checks (N);

      --  CodePeer wants to see the unexpanded N_Op_Expon node

      if CodePeer_Mode then
         return;
      end if;

      --  Relocation of left and right operands must be done after performing
      --  the validity checks since the generation of validation checks may
      --  remove side effects.

      Base   := Relocate_Node (Left_Opnd (N));
      Bastyp := Etype (Base);
      Exp    := Relocate_Node (Right_Opnd (N));
      Exptyp := Etype (Exp);

      --  If either operand is of a private type, then we have the use of an
      --  intrinsic operator, and we get rid of the privateness, by using root
      --  types of underlying types for the actual operation. Otherwise the
      --  private types will cause trouble if we expand multiplications or
      --  shifts etc. We also do this transformation if the result type is
      --  different from the base type.

      if Is_Private_Type (Etype (Base))
        or else Is_Private_Type (Typ)
        or else Is_Private_Type (Exptyp)
        or else Rtyp /= Root_Type (Bastyp)
      then
         declare
            Bt : constant Entity_Id := Root_Type (Underlying_Type (Bastyp));
            Et : constant Entity_Id := Root_Type (Underlying_Type (Exptyp));
         begin
            Rewrite (N,
              Unchecked_Convert_To (Typ,
                Make_Op_Expon (Loc,
                  Left_Opnd  => Unchecked_Convert_To (Bt, Base),
                  Right_Opnd => Unchecked_Convert_To (Et, Exp))));
            Analyze_And_Resolve (N, Typ);
            return;
         end;
      end if;

      --  Check for MINIMIZED/ELIMINATED overflow mode

      if Minimized_Eliminated_Overflow_Check (N) then
         Apply_Arithmetic_Overflow_Check (N);
         return;
      end if;

      --  Test for case of known right argument where we can replace the
      --  exponentiation by an equivalent expression using multiplication.

      --  Note: use CRT_Safe version of Compile_Time_Known_Value because in
      --  configurable run-time mode, we may not have the exponentiation
      --  routine available, and we don't want the legality of the program
      --  to depend on how clever the compiler is in knowing values.

      if CRT_Safe_Compile_Time_Known_Value (Exp) then
         Expv := Expr_Value (Exp);

         --  We only fold small non-negative exponents. You might think we
         --  could fold small negative exponents for the real case, but we
         --  can't because we are required to raise Constraint_Error for
         --  the case of 0.0 ** (negative) even if Machine_Overflows = False.
         --  See ACVC test C4A012B, and it is not worth generating the test.

         --  For small negative exponents, we return the reciprocal of
         --  the folding of the exponentiation for the opposite (positive)
         --  exponent, as required by Ada RM 4.5.6(11/3).

         if abs Expv <= 4 then

            --  X ** 0 = 1 (or 1.0)

            if Expv = 0 then

               --  Call Remove_Side_Effects to ensure that any side effects
               --  in the ignored left operand (in particular function calls
               --  to user defined functions) are properly executed.

               Remove_Side_Effects (Base);

               if Ekind (Typ) in Integer_Kind then
                  Xnode := Make_Integer_Literal (Loc, Intval => 1);
               else
                  Xnode := Make_Real_Literal (Loc, Ureal_1);
               end if;

            --  X ** 1 = X

            elsif Expv = 1 then
               Xnode := Base;

            --  X ** 2 = X * X

            elsif Expv = 2 then
               Xnode :=
                 Wrap_MA (
                   Make_Op_Multiply (Loc,
                     Left_Opnd  => Duplicate_Subexpr (Base),
                     Right_Opnd => Duplicate_Subexpr_No_Checks (Base)));

            --  X ** 3 = X * X * X

            elsif Expv = 3 then
               Xnode :=
                 Wrap_MA (
                   Make_Op_Multiply (Loc,
                     Left_Opnd =>
                       Make_Op_Multiply (Loc,
                         Left_Opnd  => Duplicate_Subexpr (Base),
                         Right_Opnd => Duplicate_Subexpr_No_Checks (Base)),
                   Right_Opnd  => Duplicate_Subexpr_No_Checks (Base)));

            --  X ** 4  ->

            --  do
            --    En : constant base'type := base * base;
            --  in
            --    En * En

            elsif Expv = 4 then
               Temp := Make_Temporary (Loc, 'E', Base);

               Xnode :=
                 Make_Expression_With_Actions (Loc,
                   Actions    => New_List (
                     Make_Object_Declaration (Loc,
                       Defining_Identifier => Temp,
                       Constant_Present    => True,
                       Object_Definition   => New_Occurrence_Of (Typ, Loc),
                       Expression =>
                         Wrap_MA (
                           Make_Op_Multiply (Loc,
                             Left_Opnd  =>
                               Duplicate_Subexpr (Base),
                             Right_Opnd =>
                               Duplicate_Subexpr_No_Checks (Base))))),

                   Expression =>
                     Wrap_MA (
                       Make_Op_Multiply (Loc,
                         Left_Opnd  => New_Occurrence_Of (Temp, Loc),
                         Right_Opnd => New_Occurrence_Of (Temp, Loc))));

            --  X ** N = 1.0 / X ** (-N)
            --  N in -4 .. -1

            else
               pragma Assert
                 (Expv = -1 or Expv = -2 or Expv = -3 or Expv = -4);

               Xnode :=
                 Make_Op_Divide (Loc,
                   Left_Opnd  =>
                     Make_Float_Literal (Loc,
                       Radix       => Uint_1,
                       Significand => Uint_1,
                       Exponent    => Uint_0),
                   Right_Opnd =>
                     Make_Op_Expon (Loc,
                       Left_Opnd  => Duplicate_Subexpr (Base),
                       Right_Opnd =>
                         Make_Integer_Literal (Loc,
                           Intval => -Expv)));
            end if;

            Rewrite (N, Xnode);
            Analyze_And_Resolve (N, Typ);
            return;
         end if;
      end if;

      --  Deal with optimizing 2 ** expression to shift where possible

      --  Note: we used to check that Exptyp was an unsigned type. But that is
      --  an unnecessary check, since if Exp is negative, we have a run-time
      --  error that is either caught (so we get the right result) or we have
      --  suppressed the check, in which case the code is erroneous anyway.

      if Is_Integer_Type (Rtyp)

        --  The base value must be "safe compile-time known", and exactly 2

        and then Nkind (Base) = N_Integer_Literal
        and then CRT_Safe_Compile_Time_Known_Value (Base)
        and then Expr_Value (Base) = Uint_2

        --  We only handle cases where the right type is a integer

        and then Is_Integer_Type (Root_Type (Exptyp))
        and then Esize (Root_Type (Exptyp)) <= Esize (Standard_Integer)

        --  This transformation is not applicable for a modular type with a
        --  nonbinary modulus because we do not handle modular reduction in
        --  a correct manner if we attempt this transformation in this case.

        and then not Non_Binary_Modulus (Typ)
      then
         --  Handle the cases where our parent is a division or multiplication
         --  specially. In these cases we can convert to using a shift at the
         --  parent level if we are not doing overflow checking, since it is
         --  too tricky to combine the overflow check at the parent level.

         if not Ovflo
           and then Nkind_In (Parent (N), N_Op_Divide, N_Op_Multiply)
         then
            declare
               P : constant Node_Id := Parent (N);
               L : constant Node_Id := Left_Opnd (P);
               R : constant Node_Id := Right_Opnd (P);

            begin
               if (Nkind (P) = N_Op_Multiply
                    and then
                      ((Is_Integer_Type (Etype (L)) and then R = N)
                          or else
                       (Is_Integer_Type (Etype (R)) and then L = N))
                    and then not Do_Overflow_Check (P))

                 or else
                  (Nkind (P) = N_Op_Divide
                    and then Is_Integer_Type (Etype (L))
                    and then Is_Unsigned_Type (Etype (L))
                    and then R = N
                    and then not Do_Overflow_Check (P))
               then
                  Set_Is_Power_Of_2_For_Shift (N);
                  return;
               end if;
            end;

         --  Here we just have 2 ** N on its own, so we can convert this to a
         --  shift node. We are prepared to deal with overflow here, and we
         --  also have to handle proper modular reduction for binary modular.

         else
            declare
               OK : Boolean;
               Lo : Uint;
               Hi : Uint;

               MaxS : Uint;
               --  Maximum shift count with no overflow

               TestS : Boolean;
               --  Set True if we must test the shift count

               Test_Gt : Node_Id;
               --  Node for test against TestS

            begin
               --  Compute maximum shift based on the underlying size. For a
               --  modular type this is one less than the size.

               if Is_Modular_Integer_Type (Typ) then

                  --  For modular integer types, this is the size of the value
                  --  being shifted minus one. Any larger values will cause
                  --  modular reduction to a result of zero. Note that we do
                  --  want the RM_Size here (e.g. mod 2 ** 7, we want a result
                  --  of 6, since 2**7 should be reduced to zero).

                  MaxS := RM_Size (Rtyp) - 1;

                  --  For signed integer types, we use the size of the value
                  --  being shifted minus 2. Larger values cause overflow.

               else
                  MaxS := Esize (Rtyp) - 2;
               end if;

               --  Determine range to see if it can be larger than MaxS

               Determine_Range
                 (Right_Opnd (N), OK, Lo, Hi, Assume_Valid => True);
               TestS := (not OK) or else Hi > MaxS;

               --  Signed integer case

               if Is_Signed_Integer_Type (Typ) then

                  --  Generate overflow check if overflow is active. Note that
                  --  we can simply ignore the possibility of overflow if the
                  --  flag is not set (means that overflow cannot happen or
                  --  that overflow checks are suppressed).

                  if Ovflo and TestS then
                     Insert_Action (N,
                       Make_Raise_Constraint_Error (Loc,
                         Condition =>
                           Make_Op_Gt (Loc,
                             Left_Opnd  => Duplicate_Subexpr (Right_Opnd (N)),
                             Right_Opnd => Make_Integer_Literal (Loc, MaxS)),
                         Reason    => CE_Overflow_Check_Failed));
                  end if;

                  --  Now rewrite node as Shift_Left (1, right-operand)

                  Rewrite (N,
                    Make_Op_Shift_Left (Loc,
                      Left_Opnd  => Make_Integer_Literal (Loc, Uint_1),
                      Right_Opnd => Right_Opnd (N)));

               --  Modular integer case

               else pragma Assert (Is_Modular_Integer_Type (Typ));

                  --  If shift count can be greater than MaxS, we need to wrap
                  --  the shift in a test that will reduce the result value to
                  --  zero if this shift count is exceeded.

                  if TestS then

                     --  Note: build node for the comparison first, before we
                     --  reuse the Right_Opnd, so that we have proper parents
                     --  in place for the Duplicate_Subexpr call.

                     Test_Gt :=
                       Make_Op_Gt (Loc,
                         Left_Opnd  => Duplicate_Subexpr (Right_Opnd (N)),
                         Right_Opnd => Make_Integer_Literal (Loc, MaxS));

                     Rewrite (N,
                       Make_If_Expression (Loc,
                         Expressions => New_List (
                           Test_Gt,
                           Make_Integer_Literal (Loc, Uint_0),
                           Make_Op_Shift_Left (Loc,
                             Left_Opnd  => Make_Integer_Literal (Loc, Uint_1),
                             Right_Opnd => Right_Opnd (N)))));

                  --  If we know shift count cannot be greater than MaxS, then
                  --  it is safe to just rewrite as a shift with no test.

                  else
                     Rewrite (N,
                       Make_Op_Shift_Left (Loc,
                         Left_Opnd  => Make_Integer_Literal (Loc, Uint_1),
                         Right_Opnd => Right_Opnd (N)));
                  end if;
               end if;

               Analyze_And_Resolve (N, Typ);
               return;
            end;
         end if;
      end if;

      --  Fall through if exponentiation must be done using a runtime routine

      --  First deal with modular case

      if Is_Modular_Integer_Type (Rtyp) then

         --  Nonbinary modular case, we call the special exponentiation
         --  routine for the nonbinary case, converting the argument to
         --  Long_Long_Integer and passing the modulus value. Then the
         --  result is converted back to the base type.

         if Non_Binary_Modulus (Rtyp) then
            Rewrite (N,
              Convert_To (Typ,
                Make_Function_Call (Loc,
                  Name                   =>
                    New_Occurrence_Of (RTE (RE_Exp_Modular), Loc),
                  Parameter_Associations => New_List (
                    Convert_To (RTE (RE_Unsigned), Base),
                    Make_Integer_Literal (Loc, Modulus (Rtyp)),
                    Exp))));

         --  Binary modular case, in this case, we call one of two routines,
         --  either the unsigned integer case, or the unsigned long long
         --  integer case, with a final "and" operation to do the required mod.

         else
            if UI_To_Int (Esize (Rtyp)) <= Standard_Integer_Size then
               Ent := RTE (RE_Exp_Unsigned);
            else
               Ent := RTE (RE_Exp_Long_Long_Unsigned);
            end if;

            Rewrite (N,
              Convert_To (Typ,
                Make_Op_And (Loc,
                  Left_Opnd  =>
                    Make_Function_Call (Loc,
                      Name                   => New_Occurrence_Of (Ent, Loc),
                      Parameter_Associations => New_List (
                        Convert_To (Etype (First_Formal (Ent)), Base),
                        Exp)),
                   Right_Opnd =>
                     Make_Integer_Literal (Loc, Modulus (Rtyp) - 1))));

         end if;

         --  Common exit point for modular type case

         Analyze_And_Resolve (N, Typ);
         return;

      --  Signed integer cases, done using either Integer or Long_Long_Integer.
      --  It is not worth having routines for Short_[Short_]Integer, since for
      --  most machines it would not help, and it would generate more code that
      --  might need certification when a certified run time is required.

      --  In the integer cases, we have two routines, one for when overflow
      --  checks are required, and one when they are not required, since there
      --  is a real gain in omitting checks on many machines.

      elsif Rtyp = Base_Type (Standard_Long_Long_Integer)
        or else (Rtyp = Base_Type (Standard_Long_Integer)
                  and then
                    Esize (Standard_Long_Integer) > Esize (Standard_Integer))
        or else Rtyp = Universal_Integer
      then
         Etyp := Standard_Long_Long_Integer;

         if Ovflo then
            Rent := RE_Exp_Long_Long_Integer;
         else
            Rent := RE_Exn_Long_Long_Integer;
         end if;

      elsif Is_Signed_Integer_Type (Rtyp) then
         Etyp := Standard_Integer;

         if Ovflo then
            Rent := RE_Exp_Integer;
         else
            Rent := RE_Exn_Integer;
         end if;

      --  Floating-point cases. We do not need separate routines for the
      --  overflow case here, since in the case of floating-point, we generate
      --  infinities anyway as a rule (either that or we automatically trap
      --  overflow), and if there is an infinity generated and a range check
      --  is required, the check will fail anyway.

      --  Historical note: we used to convert everything to Long_Long_Float
      --  and call a single common routine, but this had the undesirable effect
      --  of giving different results for small static exponent values and the
      --  same dynamic values.

      else
         pragma Assert (Is_Floating_Point_Type (Rtyp));

         if Rtyp = Standard_Float then
            Etyp := Standard_Float;
            Rent := RE_Exn_Float;

         elsif Rtyp = Standard_Long_Float then
            Etyp := Standard_Long_Float;
            Rent := RE_Exn_Long_Float;

         else
            Etyp := Standard_Long_Long_Float;
            Rent := RE_Exn_Long_Long_Float;
         end if;
      end if;

      --  Common processing for integer cases and floating-point cases.
      --  If we are in the right type, we can call runtime routine directly

      if Typ = Etyp
        and then Rtyp /= Universal_Integer
        and then Rtyp /= Universal_Real
      then
         Rewrite (N,
           Wrap_MA (
             Make_Function_Call (Loc,
               Name                   => New_Occurrence_Of (RTE (Rent), Loc),
               Parameter_Associations => New_List (Base, Exp))));

      --  Otherwise we have to introduce conversions (conversions are also
      --  required in the universal cases, since the runtime routine is
      --  typed using one of the standard types).

      else
         Rewrite (N,
           Convert_To (Typ,
             Make_Function_Call (Loc,
               Name => New_Occurrence_Of (RTE (Rent), Loc),
               Parameter_Associations => New_List (
                 Convert_To (Etyp, Base),
                 Exp))));
      end if;

      Analyze_And_Resolve (N, Typ);
      return;

   exception
      when RE_Not_Available =>
         return;
   end Expand_N_Op_Expon;

   --------------------
   -- Expand_N_Op_Ge --
   --------------------

   procedure Expand_N_Op_Ge (N : Node_Id) is
      Typ  : constant Entity_Id := Etype (N);
      Op1  : constant Node_Id   := Left_Opnd (N);
      Op2  : constant Node_Id   := Right_Opnd (N);
      Typ1 : constant Entity_Id := Base_Type (Etype (Op1));

   begin
      Binary_Op_Validity_Checks (N);

      --  Deal with overflow checks in MINIMIZED/ELIMINATED mode and if that
      --  means we no longer have a comparison operation, we are all done.

      Expand_Compare_Minimize_Eliminate_Overflow (N);

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

      --  Array type case

      if Is_Array_Type (Typ1) then
         Expand_Array_Comparison (N);
         return;
      end if;

      --  Deal with boolean operands

      if Is_Boolean_Type (Typ1) then
         Adjust_Condition (Op1);
         Adjust_Condition (Op2);
         Set_Etype (N, Standard_Boolean);
         Adjust_Result_Type (N, Typ);
      end if;

      Rewrite_Comparison (N);

      Optimize_Length_Comparison (N);
   end Expand_N_Op_Ge;

   --------------------
   -- Expand_N_Op_Gt --
   --------------------

   procedure Expand_N_Op_Gt (N : Node_Id) is
      Typ  : constant Entity_Id := Etype (N);
      Op1  : constant Node_Id   := Left_Opnd (N);
      Op2  : constant Node_Id   := Right_Opnd (N);
      Typ1 : constant Entity_Id := Base_Type (Etype (Op1));

   begin
      Binary_Op_Validity_Checks (N);

      --  Deal with overflow checks in MINIMIZED/ELIMINATED mode and if that
      --  means we no longer have a comparison operation, we are all done.

      Expand_Compare_Minimize_Eliminate_Overflow (N);

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

      --  Deal with array type operands

      if Is_Array_Type (Typ1) then
         Expand_Array_Comparison (N);
         return;
      end if;

      --  Deal with boolean type operands

      if Is_Boolean_Type (Typ1) then
         Adjust_Condition (Op1);
         Adjust_Condition (Op2);
         Set_Etype (N, Standard_Boolean);
         Adjust_Result_Type (N, Typ);
      end if;

      Rewrite_Comparison (N);

      Optimize_Length_Comparison (N);
   end Expand_N_Op_Gt;

   --------------------
   -- Expand_N_Op_Le --
   --------------------

   procedure Expand_N_Op_Le (N : Node_Id) is
      Typ  : constant Entity_Id := Etype (N);
      Op1  : constant Node_Id   := Left_Opnd (N);
      Op2  : constant Node_Id   := Right_Opnd (N);
      Typ1 : constant Entity_Id := Base_Type (Etype (Op1));

   begin
      Binary_Op_Validity_Checks (N);

      --  Deal with overflow checks in MINIMIZED/ELIMINATED mode and if that
      --  means we no longer have a comparison operation, we are all done.

      Expand_Compare_Minimize_Eliminate_Overflow (N);

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

      --  Deal with array type operands

      if Is_Array_Type (Typ1) then
         Expand_Array_Comparison (N);
         return;
      end if;

      --  Deal with Boolean type operands

      if Is_Boolean_Type (Typ1) then
         Adjust_Condition (Op1);
         Adjust_Condition (Op2);
         Set_Etype (N, Standard_Boolean);
         Adjust_Result_Type (N, Typ);
      end if;

      Rewrite_Comparison (N);

      Optimize_Length_Comparison (N);
   end Expand_N_Op_Le;

   --------------------
   -- Expand_N_Op_Lt --
   --------------------

   procedure Expand_N_Op_Lt (N : Node_Id) is
      Typ  : constant Entity_Id := Etype (N);
      Op1  : constant Node_Id   := Left_Opnd (N);
      Op2  : constant Node_Id   := Right_Opnd (N);
      Typ1 : constant Entity_Id := Base_Type (Etype (Op1));

   begin
      Binary_Op_Validity_Checks (N);

      --  Deal with overflow checks in MINIMIZED/ELIMINATED mode and if that
      --  means we no longer have a comparison operation, we are all done.

      Expand_Compare_Minimize_Eliminate_Overflow (N);

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

      --  Deal with array type operands

      if Is_Array_Type (Typ1) then
         Expand_Array_Comparison (N);
         return;
      end if;

      --  Deal with Boolean type operands

      if Is_Boolean_Type (Typ1) then
         Adjust_Condition (Op1);
         Adjust_Condition (Op2);
         Set_Etype (N, Standard_Boolean);
         Adjust_Result_Type (N, Typ);
      end if;

      Rewrite_Comparison (N);

      Optimize_Length_Comparison (N);
   end Expand_N_Op_Lt;

   -----------------------
   -- Expand_N_Op_Minus --
   -----------------------

   procedure Expand_N_Op_Minus (N : Node_Id) is
      Loc : constant Source_Ptr := Sloc (N);
      Typ : constant Entity_Id  := Etype (N);

   begin
      Unary_Op_Validity_Checks (N);

      --  Check for MINIMIZED/ELIMINATED overflow mode

      if Minimized_Eliminated_Overflow_Check (N) then
         Apply_Arithmetic_Overflow_Check (N);
         return;
      end if;

      if not Backend_Overflow_Checks_On_Target
         and then Is_Signed_Integer_Type (Etype (N))
         and then Do_Overflow_Check (N)
      then
         --  Software overflow checking expands -expr into (0 - expr)

         Rewrite (N,
           Make_Op_Subtract (Loc,
             Left_Opnd  => Make_Integer_Literal (Loc, 0),
             Right_Opnd => Right_Opnd (N)));

         Analyze_And_Resolve (N, Typ);
      end if;

      Expand_Nonbinary_Modular_Op (N);
   end Expand_N_Op_Minus;

   ---------------------
   -- Expand_N_Op_Mod --
   ---------------------

   procedure Expand_N_Op_Mod (N : Node_Id) is
      Loc   : constant Source_Ptr := Sloc (N);
      Typ   : constant Entity_Id  := Etype (N);
      DDC   : constant Boolean    := Do_Division_Check (N);

      Left  : Node_Id;
      Right : Node_Id;

      LLB : Uint;
      Llo : Uint;
      Lhi : Uint;
      LOK : Boolean;
      Rlo : Uint;
      Rhi : Uint;
      ROK : Boolean;

      pragma Warnings (Off, Lhi);

   begin
      Binary_Op_Validity_Checks (N);

      --  Check for MINIMIZED/ELIMINATED overflow mode

      if Minimized_Eliminated_Overflow_Check (N) then
         Apply_Arithmetic_Overflow_Check (N);
         return;
      end if;

      if Is_Integer_Type (Etype (N)) then
         Apply_Divide_Checks (N);

         --  All done if we don't have a MOD any more, which can happen as a
         --  result of overflow expansion in MINIMIZED or ELIMINATED modes.

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

      --  Proceed with expansion of mod operator

      Left  := Left_Opnd (N);
      Right := Right_Opnd (N);

      Determine_Range (Right, ROK, Rlo, Rhi, Assume_Valid => True);
      Determine_Range (Left,  LOK, Llo, Lhi, Assume_Valid => True);

      --  Convert mod to rem if operands are both known to be non-negative, or
      --  both known to be non-positive (these are the cases in which rem and
      --  mod are the same, see (RM 4.5.5(28-30)). We do this since it is quite
      --  likely that this will improve the quality of code, (the operation now
      --  corresponds to the hardware remainder), and it does not seem likely
      --  that it could be harmful. It also avoids some cases of the elaborate
      --  expansion in Modify_Tree_For_C mode below (since Ada rem = C %).

      if (LOK and ROK)
        and then ((Llo >= 0 and then Rlo >= 0)
                     or else
                  (Lhi <= 0 and then Rhi <= 0))
      then
         Rewrite (N,
           Make_Op_Rem (Sloc (N),
             Left_Opnd  => Left_Opnd (N),
             Right_Opnd => Right_Opnd (N)));

         --  Instead of reanalyzing the node we do the analysis manually. This
         --  avoids anomalies when the replacement is done in an instance and
         --  is epsilon more efficient.

         Set_Entity            (N, Standard_Entity (S_Op_Rem));
         Set_Etype             (N, Typ);
         Set_Do_Division_Check (N, DDC);
         Expand_N_Op_Rem (N);
         Set_Analyzed (N);
         return;

      --  Otherwise, normal mod processing

      else
         --  Apply optimization x mod 1 = 0. We don't really need that with
         --  gcc, but it is useful with other back ends and is certainly
         --  harmless.

         if Is_Integer_Type (Etype (N))
           and then Compile_Time_Known_Value (Right)
           and then Expr_Value (Right) = Uint_1
         then
            --  Call Remove_Side_Effects to ensure that any side effects in
            --  the ignored left operand (in particular function calls to
            --  user defined functions) are properly executed.

            Remove_Side_Effects (Left);

            Rewrite (N, Make_Integer_Literal (Loc, 0));
            Analyze_And_Resolve (N, Typ);
            return;
         end if;

         --  If we still have a mod operator and we are in Modify_Tree_For_C
         --  mode, and we have a signed integer type, then here is where we do
         --  the rewrite in terms of Rem. Note this rewrite bypasses the need
         --  for the special handling of the annoying case of largest negative
         --  number mod minus one.

         if Nkind (N) = N_Op_Mod
           and then Is_Signed_Integer_Type (Typ)
           and then Modify_Tree_For_C
         then
            --  In the general case, we expand A mod B as

            --    Tnn : constant typ := A rem B;
            --    ..
            --    (if (A >= 0) = (B >= 0) then Tnn
            --     elsif Tnn = 0 then 0
            --     else Tnn + B)

            --  The comparison can be written simply as A >= 0 if we know that
            --  B >= 0 which is a very common case.

            --  An important optimization is when B is known at compile time
            --  to be 2**K for some constant. In this case we can simply AND
            --  the left operand with the bit string 2**K-1 (i.e. K 1-bits)
            --  and that works for both the positive and negative cases.

            declare
               P2 : constant Nat := Power_Of_Two (Right);

            begin
               if P2 /= 0 then
                  Rewrite (N,
                    Unchecked_Convert_To (Typ,
                      Make_Op_And (Loc,
                        Left_Opnd  =>
                          Unchecked_Convert_To
                            (Corresponding_Unsigned_Type (Typ), Left),
                        Right_Opnd =>
                          Make_Integer_Literal (Loc, 2 ** P2 - 1))));
                  Analyze_And_Resolve (N, Typ);
                  return;
               end if;
            end;

            --  Here for the full rewrite

            declare
               Tnn : constant Entity_Id := Make_Temporary (Sloc (N), 'T', N);
               Cmp : Node_Id;

            begin
               Cmp :=
                 Make_Op_Ge (Loc,
                   Left_Opnd  => Duplicate_Subexpr_No_Checks (Left),
                   Right_Opnd => Make_Integer_Literal (Loc, 0));

               if not LOK or else Rlo < 0 then
                  Cmp :=
                     Make_Op_Eq (Loc,
                       Left_Opnd  => Cmp,
                       Right_Opnd =>
                         Make_Op_Ge (Loc,
                           Left_Opnd  => Duplicate_Subexpr_No_Checks (Right),
                           Right_Opnd => Make_Integer_Literal (Loc, 0)));
               end if;

               Insert_Action (N,
                 Make_Object_Declaration (Loc,
                   Defining_Identifier => Tnn,
                   Constant_Present    => True,
                   Object_Definition   => New_Occurrence_Of (Typ, Loc),
                   Expression          =>
                     Make_Op_Rem (Loc,
                       Left_Opnd  => Left,
                       Right_Opnd => Right)));

               Rewrite (N,
                 Make_If_Expression (Loc,
                   Expressions => New_List (
                     Cmp,
                     New_Occurrence_Of (Tnn, Loc),
                     Make_If_Expression (Loc,
                       Is_Elsif    => True,
                       Expressions => New_List (
                         Make_Op_Eq (Loc,
                           Left_Opnd  => New_Occurrence_Of (Tnn, Loc),
                           Right_Opnd => Make_Integer_Literal (Loc, 0)),
                         Make_Integer_Literal (Loc, 0),
                         Make_Op_Add (Loc,
                           Left_Opnd  => New_Occurrence_Of (Tnn, Loc),
                           Right_Opnd =>
                             Duplicate_Subexpr_No_Checks (Right)))))));

               Analyze_And_Resolve (N, Typ);
               return;
            end;
         end if;

         --  Deal with annoying case of largest negative number mod minus one.
         --  Gigi may not handle this case correctly, because on some targets,
         --  the mod value is computed using a divide instruction which gives
         --  an overflow trap for this case.

         --  It would be a bit more efficient to figure out which targets
         --  this is really needed for, but in practice it is reasonable
         --  to do the following special check in all cases, since it means
         --  we get a clearer message, and also the overhead is minimal given
         --  that division is expensive in any case.

         --  In fact the check is quite easy, if the right operand is -1, then
         --  the mod value is always 0, and we can just ignore the left operand
         --  completely in this case.

         --  This only applies if we still have a mod operator. Skip if we
         --  have already rewritten this (e.g. in the case of eliminated
         --  overflow checks which have driven us into bignum mode).

         if Nkind (N) = N_Op_Mod then

            --  The operand type may be private (e.g. in the expansion of an
            --  intrinsic operation) so we must use the underlying type to get
            --  the bounds, and convert the literals explicitly.

            LLB :=
              Expr_Value
                (Type_Low_Bound (Base_Type (Underlying_Type (Etype (Left)))));

            if ((not ROK) or else (Rlo <= (-1) and then (-1) <= Rhi))
              and then ((not LOK) or else (Llo = LLB))
            then
               Rewrite (N,
                 Make_If_Expression (Loc,
                   Expressions => New_List (
                     Make_Op_Eq (Loc,
                       Left_Opnd => Duplicate_Subexpr (Right),
                       Right_Opnd =>
                         Unchecked_Convert_To (Typ,
                           Make_Integer_Literal (Loc, -1))),
                     Unchecked_Convert_To (Typ,
                       Make_Integer_Literal (Loc, Uint_0)),
                     Relocate_Node (N))));

               Set_Analyzed (Next (Next (First (Expressions (N)))));
               Analyze_And_Resolve (N, Typ);
            end if;
         end if;
      end if;
   end Expand_N_Op_Mod;

   --------------------------
   -- Expand_N_Op_Multiply --
   --------------------------

   procedure Expand_N_Op_Multiply (N : Node_Id) is
      Loc : constant Source_Ptr := Sloc (N);
      Lop : constant Node_Id    := Left_Opnd (N);
      Rop : constant Node_Id    := Right_Opnd (N);

      Lp2 : constant Boolean :=
              Nkind (Lop) = N_Op_Expon and then Is_Power_Of_2_For_Shift (Lop);
      Rp2 : constant Boolean :=
              Nkind (Rop) = N_Op_Expon and then Is_Power_Of_2_For_Shift (Rop);

      Ltyp : constant Entity_Id  := Etype (Lop);
      Rtyp : constant Entity_Id  := Etype (Rop);
      Typ  : Entity_Id           := Etype (N);

   begin
      Binary_Op_Validity_Checks (N);

      --  Check for MINIMIZED/ELIMINATED overflow mode

      if Minimized_Eliminated_Overflow_Check (N) then
         Apply_Arithmetic_Overflow_Check (N);
         return;
      end if;

      --  Special optimizations for integer types

      if Is_Integer_Type (Typ) then

         --  N * 0 = 0 for integer types

         if Compile_Time_Known_Value (Rop)
           and then Expr_Value (Rop) = Uint_0
         then
            --  Call Remove_Side_Effects to ensure that any side effects in
            --  the ignored left operand (in particular function calls to
            --  user defined functions) are properly executed.

            Remove_Side_Effects (Lop);

            Rewrite (N, Make_Integer_Literal (Loc, Uint_0));
            Analyze_And_Resolve (N, Typ);
            return;
         end if;

         --  Similar handling for 0 * N = 0

         if Compile_Time_Known_Value (Lop)
           and then Expr_Value (Lop) = Uint_0
         then
            Remove_Side_Effects (Rop);
            Rewrite (N, Make_Integer_Literal (Loc, Uint_0));
            Analyze_And_Resolve (N, Typ);
            return;
         end if;

         --  N * 1 = 1 * N = N for integer types

         --  This optimisation is not done if we are going to
         --  rewrite the product 1 * 2 ** N to a shift.

         if Compile_Time_Known_Value (Rop)
           and then Expr_Value (Rop) = Uint_1
           and then not Lp2
         then
            Rewrite (N, Lop);
            return;

         elsif Compile_Time_Known_Value (Lop)
           and then Expr_Value (Lop) = Uint_1
           and then not Rp2
         then
            Rewrite (N, Rop);
            return;
         end if;
      end if;

      --  Convert x * 2 ** y to Shift_Left (x, y). Note that the fact that
      --  Is_Power_Of_2_For_Shift is set means that we know that our left
      --  operand is an integer, as required for this to work.

      if Rp2 then
         if Lp2 then

            --  Convert 2 ** A * 2 ** B into  2 ** (A + B)

            Rewrite (N,
              Make_Op_Expon (Loc,
                Left_Opnd => Make_Integer_Literal (Loc, 2),
                Right_Opnd =>
                  Make_Op_Add (Loc,
                    Left_Opnd  => Right_Opnd (Lop),
                    Right_Opnd => Right_Opnd (Rop))));
            Analyze_And_Resolve (N, Typ);
            return;

         else
            --  If the result is modular, perform the reduction of the result
            --  appropriately.

            if Is_Modular_Integer_Type (Typ)
              and then not Non_Binary_Modulus (Typ)
            then
               Rewrite (N,
                 Make_Op_And (Loc,
                   Left_Opnd  =>
                     Make_Op_Shift_Left (Loc,
                       Left_Opnd  => Lop,
                       Right_Opnd =>
                         Convert_To (Standard_Natural, Right_Opnd (Rop))),
                   Right_Opnd =>
                     Make_Integer_Literal (Loc, Modulus (Typ) - 1)));

            else
               Rewrite (N,
                 Make_Op_Shift_Left (Loc,
                   Left_Opnd  => Lop,
                   Right_Opnd =>
                     Convert_To (Standard_Natural, Right_Opnd (Rop))));
            end if;

            Analyze_And_Resolve (N, Typ);
            return;
         end if;

      --  Same processing for the operands the other way round

      elsif Lp2 then
         if Is_Modular_Integer_Type (Typ)
           and then not Non_Binary_Modulus (Typ)
         then
            Rewrite (N,
              Make_Op_And (Loc,
                Left_Opnd  =>
                  Make_Op_Shift_Left (Loc,
                    Left_Opnd  => Rop,
                    Right_Opnd =>
                      Convert_To (Standard_Natural, Right_Opnd (Lop))),
                Right_Opnd =>
                   Make_Integer_Literal (Loc, Modulus (Typ) - 1)));

         else
            Rewrite (N,
              Make_Op_Shift_Left (Loc,
                Left_Opnd  => Rop,
                Right_Opnd =>
                  Convert_To (Standard_Natural, Right_Opnd (Lop))));
         end if;

         Analyze_And_Resolve (N, Typ);
         return;
      end if;

      --  Do required fixup of universal fixed operation

      if Typ = Universal_Fixed then
         Fixup_Universal_Fixed_Operation (N);
         Typ := Etype (N);
      end if;

      --  Multiplications with fixed-point results

      if Is_Fixed_Point_Type (Typ) then

         --  No special processing if Treat_Fixed_As_Integer is set, since from
         --  a semantic point of view such operations are simply integer
         --  operations and will be treated that way.

         if not Treat_Fixed_As_Integer (N) then

            --  Case of fixed * integer => fixed

            if Is_Integer_Type (Rtyp) then
               Expand_Multiply_Fixed_By_Integer_Giving_Fixed (N);

            --  Case of integer * fixed => fixed

            elsif Is_Integer_Type (Ltyp) then
               Expand_Multiply_Integer_By_Fixed_Giving_Fixed (N);

            --  Case of fixed * fixed => fixed

            else
               Expand_Multiply_Fixed_By_Fixed_Giving_Fixed (N);
            end if;
         end if;

      --  Other cases of multiplication of fixed-point operands. Again we
      --  exclude the cases where Treat_Fixed_As_Integer flag is set.

      elsif (Is_Fixed_Point_Type (Ltyp) or else Is_Fixed_Point_Type (Rtyp))
        and then not Treat_Fixed_As_Integer (N)
      then
         if Is_Integer_Type (Typ) then
            Expand_Multiply_Fixed_By_Fixed_Giving_Integer (N);
         else
            pragma Assert (Is_Floating_Point_Type (Typ));
            Expand_Multiply_Fixed_By_Fixed_Giving_Float (N);
         end if;

      --  Mixed-mode operations can appear in a non-static universal context,
      --  in which case the integer argument must be converted explicitly.

      elsif Typ = Universal_Real and then Is_Integer_Type (Rtyp) then
         Rewrite (Rop, Convert_To (Universal_Real, Relocate_Node (Rop)));
         Analyze_And_Resolve (Rop, Universal_Real);

      elsif Typ = Universal_Real and then Is_Integer_Type (Ltyp) then
         Rewrite (Lop, Convert_To (Universal_Real, Relocate_Node (Lop)));
         Analyze_And_Resolve (Lop, Universal_Real);

      --  Non-fixed point cases, check software overflow checking required

      elsif Is_Signed_Integer_Type (Etype (N)) then
         Apply_Arithmetic_Overflow_Check (N);
      end if;

      --  Overflow checks for floating-point if -gnateF mode active

      Check_Float_Op_Overflow (N);

      Expand_Nonbinary_Modular_Op (N);
   end Expand_N_Op_Multiply;

   --------------------
   -- Expand_N_Op_Ne --
   --------------------

   procedure Expand_N_Op_Ne (N : Node_Id) is
      Typ : constant Entity_Id := Etype (Left_Opnd (N));

   begin
      --  Case of elementary type with standard operator. But if unnesting,
      --  handle elementary types whose Equivalent_Types are records because
      --  there may be padding or undefined fields.

      if Is_Elementary_Type (Typ)
        and then Sloc (Entity (N)) = Standard_Location
        and then not (Ekind_In (Typ, E_Class_Wide_Type,
                                E_Class_Wide_Subtype,
                                E_Access_Subprogram_Type,
                                E_Access_Protected_Subprogram_Type,
                                E_Anonymous_Access_Protected_Subprogram_Type,
                                E_Access_Subprogram_Type,
                                E_Exception_Type)
                        and then Present (Equivalent_Type (Typ))
                        and then Is_Record_Type (Equivalent_Type (Typ)))
      then
         Binary_Op_Validity_Checks (N);

         --  Deal with overflow checks in MINIMIZED/ELIMINATED mode and if
         --  means we no longer have a /= operation, we are all done.

         Expand_Compare_Minimize_Eliminate_Overflow (N);

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

         --  Boolean types (requiring handling of non-standard case)

         if Is_Boolean_Type (Typ) then
            Adjust_Condition (Left_Opnd (N));
            Adjust_Condition (Right_Opnd (N));
            Set_Etype (N, Standard_Boolean);
            Adjust_Result_Type (N, Typ);
         end if;

         Rewrite_Comparison (N);

      --  For all cases other than elementary types, we rewrite node as the
      --  negation of an equality operation, and reanalyze. The equality to be
      --  used is defined in the same scope and has the same signature. This
      --  signature must be set explicitly since in an instance it may not have
      --  the same visibility as in the generic unit. This avoids duplicating
      --  or factoring the complex code for record/array equality tests etc.

      --  This case is also used for the minimal expansion performed in
      --  GNATprove mode.

      else
         declare
            Loc : constant Source_Ptr := Sloc (N);
            Neg : Node_Id;
            Ne  : constant Entity_Id := Entity (N);

         begin
            Binary_Op_Validity_Checks (N);

            Neg :=
              Make_Op_Not (Loc,
                Right_Opnd =>
                  Make_Op_Eq (Loc,
                    Left_Opnd =>  Left_Opnd (N),
                    Right_Opnd => Right_Opnd (N)));

            --  The level of parentheses is useless in GNATprove mode, and
            --  bumping its level here leads to wrong columns being used in
            --  check messages, hence skip it in this mode.

            if not GNATprove_Mode then
               Set_Paren_Count (Right_Opnd (Neg), 1);
            end if;

            if Scope (Ne) /= Standard_Standard then
               Set_Entity (Right_Opnd (Neg), Corresponding_Equality (Ne));
            end if;

            --  For navigation purposes, we want to treat the inequality as an
            --  implicit reference to the corresponding equality. Preserve the
            --  Comes_From_ source flag to generate proper Xref entries.

            Preserve_Comes_From_Source (Neg, N);
            Preserve_Comes_From_Source (Right_Opnd (Neg), N);
            Rewrite (N, Neg);
            Analyze_And_Resolve (N, Standard_Boolean);
         end;
      end if;

      --  No need for optimization in GNATprove mode, where we would rather see
      --  the original source expression.

      if not GNATprove_Mode then
         Optimize_Length_Comparison (N);
      end if;
   end Expand_N_Op_Ne;

   ---------------------
   -- Expand_N_Op_Not --
   ---------------------

   --  If the argument is other than a Boolean array type, there is no special
   --  expansion required, except for dealing with validity checks, and non-
   --  standard boolean representations.

   --  For the packed array case, we call the special routine in Exp_Pakd,
   --  except that if the component size is greater than one, we use the
   --  standard routine generating a gruesome loop (it is so peculiar to have
   --  packed arrays with non-standard Boolean representations anyway, so it
   --  does not matter that we do not handle this case efficiently).

   --  For the unpacked array case (and for the special packed case where we
   --  have non standard Booleans, as discussed above), we generate and insert
   --  into the tree the following function definition:

   --     function Nnnn (A : arr) is
   --       B : arr;
   --     begin
   --       for J in a'range loop
   --          B (J) := not A (J);
   --       end loop;
   --       return B;
   --     end Nnnn;

   --  Here arr is the actual subtype of the parameter (and hence always
   --  constrained). Then we replace the not with a call to this function.

   procedure Expand_N_Op_Not (N : Node_Id) is
      Loc  : constant Source_Ptr := Sloc (N);
      Typ  : constant Entity_Id  := Etype (N);
      Opnd : Node_Id;
      Arr  : Entity_Id;
      A    : Entity_Id;
      B    : Entity_Id;
      J    : Entity_Id;
      A_J  : Node_Id;
      B_J  : Node_Id;

      Func_Name      : Entity_Id;
      Loop_Statement : Node_Id;

   begin
      Unary_Op_Validity_Checks (N);

      --  For boolean operand, deal with non-standard booleans

      if Is_Boolean_Type (Typ) then
         Adjust_Condition (Right_Opnd (N));
         Set_Etype (N, Standard_Boolean);
         Adjust_Result_Type (N, Typ);
         return;
      end if;

      --  Only array types need any other processing

      if not Is_Array_Type (Typ) then
         return;
      end if;

      --  Case of array operand. If bit packed with a component size of 1,
      --  handle it in Exp_Pakd if the operand is known to be aligned.

      if Is_Bit_Packed_Array (Typ)
        and then Component_Size (Typ) = 1
        and then not Is_Possibly_Unaligned_Object (Right_Opnd (N))
      then
         Expand_Packed_Not (N);
         return;
      end if;

      --  Case of array operand which is not bit-packed. If the context is
      --  a safe assignment, call in-place operation, If context is a larger
      --  boolean expression in the context of a safe assignment, expansion is
      --  done by enclosing operation.

      Opnd := Relocate_Node (Right_Opnd (N));
      Convert_To_Actual_Subtype (Opnd);
      Arr := Etype (Opnd);
      Ensure_Defined (Arr, N);
      Silly_Boolean_Array_Not_Test (N, Arr);

      if Nkind (Parent (N)) = N_Assignment_Statement then
         if Safe_In_Place_Array_Op (Name (Parent (N)), N, Empty) then
            Build_Boolean_Array_Proc_Call (Parent (N), Opnd, Empty);
            return;

         --  Special case the negation of a binary operation

         elsif Nkind_In (Opnd, N_Op_And, N_Op_Or, N_Op_Xor)
           and then Safe_In_Place_Array_Op
                      (Name (Parent (N)), Left_Opnd (Opnd), Right_Opnd (Opnd))
         then
            Build_Boolean_Array_Proc_Call (Parent (N), Opnd, Empty);
            return;
         end if;

      elsif Nkind (Parent (N)) in N_Binary_Op
        and then Nkind (Parent (Parent (N))) = N_Assignment_Statement
      then
         declare
            Op1 : constant Node_Id := Left_Opnd  (Parent (N));
            Op2 : constant Node_Id := Right_Opnd (Parent (N));
            Lhs : constant Node_Id := Name (Parent (Parent (N)));

         begin
            if Safe_In_Place_Array_Op (Lhs, Op1, Op2) then

               --  (not A) op (not B) can be reduced to a single call

               if N = Op1 and then Nkind (Op2) = N_Op_Not then
                  return;

               elsif N = Op2 and then Nkind (Op1) = N_Op_Not then
                  return;

               --  A xor (not B) can also be special-cased

               elsif N = Op2 and then Nkind (Parent (N)) = N_Op_Xor then
                  return;
               end if;
            end if;
         end;
      end if;

      A := Make_Defining_Identifier (Loc, Name_uA);
      B := Make_Defining_Identifier (Loc, Name_uB);
      J := Make_Defining_Identifier (Loc, Name_uJ);

      A_J :=
        Make_Indexed_Component (Loc,
          Prefix      => New_Occurrence_Of (A, Loc),
          Expressions => New_List (New_Occurrence_Of (J, Loc)));

      B_J :=
        Make_Indexed_Component (Loc,
          Prefix      => New_Occurrence_Of (B, Loc),
          Expressions => New_List (New_Occurrence_Of (J, Loc)));

      Loop_Statement :=
        Make_Implicit_Loop_Statement (N,
          Identifier => Empty,

          Iteration_Scheme =>
            Make_Iteration_Scheme (Loc,
              Loop_Parameter_Specification =>
                Make_Loop_Parameter_Specification (Loc,
                  Defining_Identifier         => J,
                  Discrete_Subtype_Definition =>
                    Make_Attribute_Reference (Loc,
                      Prefix         => Make_Identifier (Loc, Chars (A)),
                      Attribute_Name => Name_Range))),

          Statements => New_List (
            Make_Assignment_Statement (Loc,
              Name       => B_J,
              Expression => Make_Op_Not (Loc, A_J))));

      Func_Name := Make_Temporary (Loc, 'N');
      Set_Is_Inlined (Func_Name);

      Insert_Action (N,
        Make_Subprogram_Body (Loc,
          Specification =>
            Make_Function_Specification (Loc,
              Defining_Unit_Name => Func_Name,
              Parameter_Specifications => New_List (
                Make_Parameter_Specification (Loc,
                  Defining_Identifier => A,
                  Parameter_Type      => New_Occurrence_Of (Typ, Loc))),
              Result_Definition => New_Occurrence_Of (Typ, Loc)),

          Declarations => New_List (
            Make_Object_Declaration (Loc,
              Defining_Identifier => B,
              Object_Definition   => New_Occurrence_Of (Arr, Loc))),

          Handled_Statement_Sequence =>
            Make_Handled_Sequence_Of_Statements (Loc,
              Statements => New_List (
                Loop_Statement,
                Make_Simple_Return_Statement (Loc,
                  Expression => Make_Identifier (Loc, Chars (B)))))));

      Rewrite (N,
        Make_Function_Call (Loc,
          Name                   => New_Occurrence_Of (Func_Name, Loc),
          Parameter_Associations => New_List (Opnd)));

      Analyze_And_Resolve (N, Typ);
   end Expand_N_Op_Not;

   --------------------
   -- Expand_N_Op_Or --
   --------------------

   procedure Expand_N_Op_Or (N : Node_Id) is
      Typ : constant Entity_Id := Etype (N);

   begin
      Binary_Op_Validity_Checks (N);

      if Is_Array_Type (Etype (N)) then
         Expand_Boolean_Operator (N);

      elsif Is_Boolean_Type (Etype (N)) then
         Adjust_Condition (Left_Opnd (N));
         Adjust_Condition (Right_Opnd (N));
         Set_Etype (N, Standard_Boolean);
         Adjust_Result_Type (N, Typ);

      elsif Is_Intrinsic_Subprogram (Entity (N)) then
         Expand_Intrinsic_Call (N, Entity (N));
      end if;

      Expand_Nonbinary_Modular_Op (N);
   end Expand_N_Op_Or;

   ----------------------
   -- Expand_N_Op_Plus --
   ----------------------

   procedure Expand_N_Op_Plus (N : Node_Id) is
   begin
      Unary_Op_Validity_Checks (N);

      --  Check for MINIMIZED/ELIMINATED overflow mode

      if Minimized_Eliminated_Overflow_Check (N) then
         Apply_Arithmetic_Overflow_Check (N);
         return;
      end if;
   end Expand_N_Op_Plus;

   ---------------------
   -- Expand_N_Op_Rem --
   ---------------------

   procedure Expand_N_Op_Rem (N : Node_Id) is
      Loc : constant Source_Ptr := Sloc (N);
      Typ : constant Entity_Id  := Etype (N);

      Left  : Node_Id;
      Right : Node_Id;

      Lo : Uint;
      Hi : Uint;
      OK : Boolean;

      Lneg : Boolean;
      Rneg : Boolean;
      --  Set if corresponding operand can be negative

      pragma Unreferenced (Hi);

   begin
      Binary_Op_Validity_Checks (N);

      --  Check for MINIMIZED/ELIMINATED overflow mode

      if Minimized_Eliminated_Overflow_Check (N) then
         Apply_Arithmetic_Overflow_Check (N);
         return;
      end if;

      if Is_Integer_Type (Etype (N)) then
         Apply_Divide_Checks (N);

         --  All done if we don't have a REM any more, which can happen as a
         --  result of overflow expansion in MINIMIZED or ELIMINATED modes.

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

      --  Proceed with expansion of REM

      Left  := Left_Opnd (N);
      Right := Right_Opnd (N);

      --  Apply optimization x rem 1 = 0. We don't really need that with gcc,
      --  but it is useful with other back ends, and is certainly harmless.

      if Is_Integer_Type (Etype (N))
        and then Compile_Time_Known_Value (Right)
        and then Expr_Value (Right) = Uint_1
      then
         --  Call Remove_Side_Effects to ensure that any side effects in the
         --  ignored left operand (in particular function calls to user defined
         --  functions) are properly executed.

         Remove_Side_Effects (Left);

         Rewrite (N, Make_Integer_Literal (Loc, 0));
         Analyze_And_Resolve (N, Typ);
         return;
      end if;

      --  Deal with annoying case of largest negative number remainder minus
      --  one. Gigi may not handle this case correctly, because on some
      --  targets, the mod value is computed using a divide instruction
      --  which gives an overflow trap for this case.

      --  It would be a bit more efficient to figure out which targets this
      --  is really needed for, but in practice it is reasonable to do the
      --  following special check in all cases, since it means we get a clearer
      --  message, and also the overhead is minimal given that division is
      --  expensive in any case.

      --  In fact the check is quite easy, if the right operand is -1, then
      --  the remainder is always 0, and we can just ignore the left operand
      --  completely in this case.

      Determine_Range (Right, OK, Lo, Hi, Assume_Valid => True);
      Lneg := (not OK) or else Lo < 0;

      Determine_Range (Left,  OK, Lo, Hi, Assume_Valid => True);
      Rneg := (not OK) or else Lo < 0;

      --  We won't mess with trying to find out if the left operand can really
      --  be the largest negative number (that's a pain in the case of private
      --  types and this is really marginal). We will just assume that we need
      --  the test if the left operand can be negative at all.

      if Lneg and Rneg then
         Rewrite (N,
           Make_If_Expression (Loc,
             Expressions => New_List (
               Make_Op_Eq (Loc,
                 Left_Opnd  => Duplicate_Subexpr (Right),
                 Right_Opnd =>
                   Unchecked_Convert_To (Typ, Make_Integer_Literal (Loc, -1))),

               Unchecked_Convert_To (Typ,
                 Make_Integer_Literal (Loc, Uint_0)),

               Relocate_Node (N))));

         Set_Analyzed (Next (Next (First (Expressions (N)))));
         Analyze_And_Resolve (N, Typ);
      end if;
   end Expand_N_Op_Rem;

   -----------------------------
   -- Expand_N_Op_Rotate_Left --
   -----------------------------

   procedure Expand_N_Op_Rotate_Left (N : Node_Id) is
   begin
      Binary_Op_Validity_Checks (N);

      --  If we are in Modify_Tree_For_C mode, there is no rotate left in C,
      --  so we rewrite in terms of logical shifts

      --    Shift_Left (Num, Bits) or Shift_Right (num, Esize - Bits)

      --  where Bits is the shift count mod Esize (the mod operation here
      --  deals with ludicrous large shift counts, which are apparently OK).

      --  What about nonbinary modulus ???

      declare
         Loc : constant Source_Ptr := Sloc (N);
         Rtp : constant Entity_Id  := Etype (Right_Opnd (N));
         Typ : constant Entity_Id  := Etype (N);

      begin
         if Modify_Tree_For_C then
            Rewrite (Right_Opnd (N),
              Make_Op_Rem (Loc,
                Left_Opnd  => Relocate_Node (Right_Opnd (N)),
                Right_Opnd => Make_Integer_Literal (Loc, Esize (Typ))));

            Analyze_And_Resolve (Right_Opnd (N), Rtp);

            Rewrite (N,
              Make_Op_Or (Loc,
                Left_Opnd =>
                  Make_Op_Shift_Left (Loc,
                    Left_Opnd  => Left_Opnd (N),
                    Right_Opnd => Right_Opnd (N)),

                Right_Opnd =>
                  Make_Op_Shift_Right (Loc,
                    Left_Opnd  => Duplicate_Subexpr_No_Checks (Left_Opnd (N)),
                    Right_Opnd =>
                      Make_Op_Subtract (Loc,
                        Left_Opnd  => Make_Integer_Literal (Loc, Esize (Typ)),
                        Right_Opnd =>
                          Duplicate_Subexpr_No_Checks (Right_Opnd (N))))));

            Analyze_And_Resolve (N, Typ);
         end if;
      end;
   end Expand_N_Op_Rotate_Left;

   ------------------------------
   -- Expand_N_Op_Rotate_Right --
   ------------------------------

   procedure Expand_N_Op_Rotate_Right (N : Node_Id) is
   begin
      Binary_Op_Validity_Checks (N);

      --  If we are in Modify_Tree_For_C mode, there is no rotate right in C,
      --  so we rewrite in terms of logical shifts

      --    Shift_Right (Num, Bits) or Shift_Left (num, Esize - Bits)

      --  where Bits is the shift count mod Esize (the mod operation here
      --  deals with ludicrous large shift counts, which are apparently OK).

      --  What about nonbinary modulus ???

      declare
         Loc : constant Source_Ptr := Sloc (N);
         Rtp : constant Entity_Id  := Etype (Right_Opnd (N));
         Typ : constant Entity_Id  := Etype (N);

      begin
         Rewrite (Right_Opnd (N),
           Make_Op_Rem (Loc,
             Left_Opnd  => Relocate_Node (Right_Opnd (N)),
             Right_Opnd => Make_Integer_Literal (Loc, Esize (Typ))));

         Analyze_And_Resolve (Right_Opnd (N), Rtp);

         if Modify_Tree_For_C then
            Rewrite (N,
              Make_Op_Or (Loc,
                Left_Opnd =>
                  Make_Op_Shift_Right (Loc,
                    Left_Opnd  => Left_Opnd (N),
                    Right_Opnd => Right_Opnd (N)),

                Right_Opnd =>
                  Make_Op_Shift_Left (Loc,
                    Left_Opnd  => Duplicate_Subexpr_No_Checks (Left_Opnd (N)),
                    Right_Opnd =>
                      Make_Op_Subtract (Loc,
                        Left_Opnd  => Make_Integer_Literal (Loc, Esize (Typ)),
                        Right_Opnd =>
                          Duplicate_Subexpr_No_Checks (Right_Opnd (N))))));

            Analyze_And_Resolve (N, Typ);
         end if;
      end;
   end Expand_N_Op_Rotate_Right;

   ----------------------------
   -- Expand_N_Op_Shift_Left --
   ----------------------------

   --  Note: nothing in this routine depends on left as opposed to right shifts
   --  so we share the routine for expanding shift right operations.

   procedure Expand_N_Op_Shift_Left (N : Node_Id) is
   begin
      Binary_Op_Validity_Checks (N);

      --  If we are in Modify_Tree_For_C mode, then ensure that the right
      --  operand is not greater than the word size (since that would not
      --  be defined properly by the corresponding C shift operator).

      if Modify_Tree_For_C then
         declare
            Right : constant Node_Id    := Right_Opnd (N);
            Loc   : constant Source_Ptr := Sloc (Right);
            Typ   : constant Entity_Id  := Etype (N);
            Siz   : constant Uint       := Esize (Typ);
            Orig  : Node_Id;
            OK    : Boolean;
            Lo    : Uint;
            Hi    : Uint;

         begin
            if Compile_Time_Known_Value (Right) then
               if Expr_Value (Right) >= Siz then
                  Rewrite (N, Make_Integer_Literal (Loc, 0));
                  Analyze_And_Resolve (N, Typ);
               end if;

            --  Not compile time known, find range

            else
               Determine_Range (Right, OK, Lo, Hi, Assume_Valid => True);

               --  Nothing to do if known to be OK range, otherwise expand

               if not OK or else Hi >= Siz then

                  --  Prevent recursion on copy of shift node

                  Orig := Relocate_Node (N);
                  Set_Analyzed (Orig);

                  --  Now do the rewrite

                  Rewrite (N,
                     Make_If_Expression (Loc,
                       Expressions => New_List (
                         Make_Op_Ge (Loc,
                           Left_Opnd  => Duplicate_Subexpr_Move_Checks (Right),
                           Right_Opnd => Make_Integer_Literal (Loc, Siz)),
                         Make_Integer_Literal (Loc, 0),
                         Orig)));
                  Analyze_And_Resolve (N, Typ);
               end if;
            end if;
         end;
      end if;
   end Expand_N_Op_Shift_Left;

   -----------------------------
   -- Expand_N_Op_Shift_Right --
   -----------------------------

   procedure Expand_N_Op_Shift_Right (N : Node_Id) is
   begin
      --  Share shift left circuit

      Expand_N_Op_Shift_Left (N);
   end Expand_N_Op_Shift_Right;

   ----------------------------------------
   -- Expand_N_Op_Shift_Right_Arithmetic --
   ----------------------------------------

   procedure Expand_N_Op_Shift_Right_Arithmetic (N : Node_Id) is
   begin
      Binary_Op_Validity_Checks (N);

      --  If we are in Modify_Tree_For_C mode, there is no shift right
      --  arithmetic in C, so we rewrite in terms of logical shifts.

      --    Shift_Right (Num, Bits) or
      --      (if Num >= Sign
      --       then not (Shift_Right (Mask, bits))
      --       else 0)

      --  Here Mask is all 1 bits (2**size - 1), and Sign is 2**(size - 1)

      --  Note: in almost all C compilers it would work to just shift a
      --  signed integer right, but it's undefined and we cannot rely on it.

      --  Note: the above works fine for shift counts greater than or equal
      --  to the word size, since in this case (not (Shift_Right (Mask, bits)))
      --  generates all 1'bits.

      --  What about nonbinary modulus ???

      declare
         Loc   : constant Source_Ptr := Sloc (N);
         Typ   : constant Entity_Id  := Etype (N);
         Sign  : constant Uint       := 2 ** (Esize (Typ) - 1);
         Mask  : constant Uint       := (2 ** Esize (Typ)) - 1;
         Left  : constant Node_Id    := Left_Opnd (N);
         Right : constant Node_Id    := Right_Opnd (N);
         Maskx : Node_Id;

      begin
         if Modify_Tree_For_C then

            --  Here if not (Shift_Right (Mask, bits)) can be computed at
            --  compile time as a single constant.

            if Compile_Time_Known_Value (Right) then
               declare
                  Val : constant Uint := Expr_Value (Right);

               begin
                  if Val >= Esize (Typ) then
                     Maskx := Make_Integer_Literal (Loc, Mask);

                  else
                     Maskx :=
                       Make_Integer_Literal (Loc,
                         Intval => Mask - (Mask / (2 ** Expr_Value (Right))));
                  end if;
               end;

            else
               Maskx :=
                 Make_Op_Not (Loc,
                   Right_Opnd =>
                     Make_Op_Shift_Right (Loc,
                       Left_Opnd  => Make_Integer_Literal (Loc, Mask),
                       Right_Opnd => Duplicate_Subexpr_No_Checks (Right)));
            end if;

            --  Now do the rewrite

            Rewrite (N,
              Make_Op_Or (Loc,
                Left_Opnd =>
                  Make_Op_Shift_Right (Loc,
                    Left_Opnd  => Left,
                    Right_Opnd => Right),
                Right_Opnd =>
                  Make_If_Expression (Loc,
                    Expressions => New_List (
                      Make_Op_Ge (Loc,
                        Left_Opnd  => Duplicate_Subexpr_No_Checks (Left),
                        Right_Opnd => Make_Integer_Literal (Loc, Sign)),
                      Maskx,
                      Make_Integer_Literal (Loc, 0)))));
            Analyze_And_Resolve (N, Typ);
         end if;
      end;
   end Expand_N_Op_Shift_Right_Arithmetic;

   --------------------------
   -- Expand_N_Op_Subtract --
   --------------------------

   procedure Expand_N_Op_Subtract (N : Node_Id) is
      Typ : constant Entity_Id := Etype (N);

   begin
      Binary_Op_Validity_Checks (N);

      --  Check for MINIMIZED/ELIMINATED overflow mode

      if Minimized_Eliminated_Overflow_Check (N) then
         Apply_Arithmetic_Overflow_Check (N);
         return;
      end if;

      --  N - 0 = N for integer types

      if Is_Integer_Type (Typ)
        and then Compile_Time_Known_Value (Right_Opnd (N))
        and then Expr_Value (Right_Opnd (N)) = 0
      then
         Rewrite (N, Left_Opnd (N));
         return;
      end if;

      --  Arithmetic overflow checks for signed integer/fixed point types

      if Is_Signed_Integer_Type (Typ) or else Is_Fixed_Point_Type (Typ) then
         Apply_Arithmetic_Overflow_Check (N);
      end if;

      --  Overflow checks for floating-point if -gnateF mode active

      Check_Float_Op_Overflow (N);

      Expand_Nonbinary_Modular_Op (N);
   end Expand_N_Op_Subtract;

   ---------------------
   -- Expand_N_Op_Xor --
   ---------------------

   procedure Expand_N_Op_Xor (N : Node_Id) is
      Typ : constant Entity_Id := Etype (N);

   begin
      Binary_Op_Validity_Checks (N);

      if Is_Array_Type (Etype (N)) then
         Expand_Boolean_Operator (N);

      elsif Is_Boolean_Type (Etype (N)) then
         Adjust_Condition (Left_Opnd (N));
         Adjust_Condition (Right_Opnd (N));
         Set_Etype (N, Standard_Boolean);
         Adjust_Result_Type (N, Typ);

      elsif Is_Intrinsic_Subprogram (Entity (N)) then
         Expand_Intrinsic_Call (N, Entity (N));
      end if;

      Expand_Nonbinary_Modular_Op (N);
   end Expand_N_Op_Xor;

   ----------------------
   -- Expand_N_Or_Else --
   ----------------------

   procedure Expand_N_Or_Else (N : Node_Id)
     renames Expand_Short_Circuit_Operator;

   -----------------------------------
   -- Expand_N_Qualified_Expression --
   -----------------------------------

   procedure Expand_N_Qualified_Expression (N : Node_Id) is
      Operand     : constant Node_Id   := Expression (N);
      Target_Type : constant Entity_Id := Entity (Subtype_Mark (N));

   begin
      --  Do validity check if validity checking operands

      if Validity_Checks_On and Validity_Check_Operands then
         Ensure_Valid (Operand);
      end if;

      --  Apply possible constraint check

      Apply_Constraint_Check (Operand, Target_Type, No_Sliding => True);

      if Do_Range_Check (Operand) then
         Generate_Range_Check (Operand, Target_Type, CE_Range_Check_Failed);
      end if;
   end Expand_N_Qualified_Expression;

   ------------------------------------
   -- Expand_N_Quantified_Expression --
   ------------------------------------

   --  We expand:

   --    for all X in range => Cond

   --  into:

   --        T := True;
   --        for X in range loop
   --           if not Cond then
   --              T := False;
   --              exit;
   --           end if;
   --        end loop;

   --  Similarly, an existentially quantified expression:

   --    for some X in range => Cond

   --  becomes:

   --        T := False;
   --        for X in range loop
   --           if Cond then
   --              T := True;
   --              exit;
   --           end if;
   --        end loop;

   --  In both cases, the iteration may be over a container in which case it is
   --  given by an iterator specification, not a loop parameter specification.

   procedure Expand_N_Quantified_Expression (N : Node_Id) is
      Actions   : constant List_Id    := New_List;
      For_All   : constant Boolean    := All_Present (N);
      Iter_Spec : constant Node_Id    := Iterator_Specification (N);
      Loc       : constant Source_Ptr := Sloc (N);
      Loop_Spec : constant Node_Id    := Loop_Parameter_Specification (N);
      Cond      : Node_Id;
      Flag      : Entity_Id;
      Scheme    : Node_Id;
      Stmts     : List_Id;
      Var       : Entity_Id;

   begin
      --  Ensure that the bound variable is properly frozen. We must do
      --  this before expansion because the expression is about to be
      --  converted into a loop, and resulting freeze nodes may end up
      --  in the wrong place in the tree.

      if Present (Iter_Spec) then
         Var := Defining_Identifier (Iter_Spec);
      else
         Var := Defining_Identifier (Loop_Spec);
      end if;

      declare
         P : Node_Id := Parent (N);
      begin
         while Nkind (P) in N_Subexpr loop
            P := Parent (P);
         end loop;

         Freeze_Before (P, Etype (Var));
      end;

      --  Create the declaration of the flag which tracks the status of the
      --  quantified expression. Generate:

      --    Flag : Boolean := (True | False);

      Flag := Make_Temporary (Loc, 'T', N);

      Append_To (Actions,
        Make_Object_Declaration (Loc,
          Defining_Identifier => Flag,
          Object_Definition   => New_Occurrence_Of (Standard_Boolean, Loc),
          Expression          =>
            New_Occurrence_Of (Boolean_Literals (For_All), Loc)));

      --  Construct the circuitry which tracks the status of the quantified
      --  expression. Generate:

      --    if [not] Cond then
      --       Flag := (False | True);
      --       exit;
      --    end if;

      Cond := Relocate_Node (Condition (N));

      if For_All then
         Cond := Make_Op_Not (Loc, Cond);
      end if;

      Stmts := New_List (
        Make_Implicit_If_Statement (N,
          Condition       => Cond,
          Then_Statements => New_List (
            Make_Assignment_Statement (Loc,
              Name       => New_Occurrence_Of (Flag, Loc),
              Expression =>
                New_Occurrence_Of (Boolean_Literals (not For_All), Loc)),
            Make_Exit_Statement (Loc))));

      --  Build the loop equivalent of the quantified expression

      if Present (Iter_Spec) then
         Scheme :=
           Make_Iteration_Scheme (Loc,
             Iterator_Specification => Iter_Spec);
      else
         Scheme :=
           Make_Iteration_Scheme (Loc,
             Loop_Parameter_Specification => Loop_Spec);
      end if;

      Append_To (Actions,
        Make_Loop_Statement (Loc,
          Iteration_Scheme => Scheme,
          Statements       => Stmts,
          End_Label        => Empty));

      --  Transform the quantified expression

      Rewrite (N,
        Make_Expression_With_Actions (Loc,
          Expression => New_Occurrence_Of (Flag, Loc),
          Actions    => Actions));
      Analyze_And_Resolve (N, Standard_Boolean);
   end Expand_N_Quantified_Expression;

   ---------------------------------
   -- Expand_N_Selected_Component --
   ---------------------------------

   procedure Expand_N_Selected_Component (N : Node_Id) is
      Loc   : constant Source_Ptr := Sloc (N);
      Par   : constant Node_Id    := Parent (N);
      P     : constant Node_Id    := Prefix (N);
      S     : constant Node_Id    := Selector_Name (N);
      Ptyp  : Entity_Id           := Underlying_Type (Etype (P));
      Disc  : Entity_Id;
      New_N : Node_Id;
      Dcon  : Elmt_Id;
      Dval  : Node_Id;

      function In_Left_Hand_Side (Comp : Node_Id) return Boolean;
      --  Gigi needs a temporary for prefixes that depend on a discriminant,
      --  unless the context of an assignment can provide size information.
      --  Don't we have a general routine that does this???

      function Is_Subtype_Declaration return Boolean;
      --  The replacement of a discriminant reference by its value is required
      --  if this is part of the initialization of an temporary generated by a
      --  change of representation. This shows up as the construction of a
      --  discriminant constraint for a subtype declared at the same point as
      --  the entity in the prefix of the selected component. We recognize this
      --  case when the context of the reference is:
      --    subtype ST is T(Obj.D);
      --  where the entity for Obj comes from source, and ST has the same sloc.

      -----------------------
      -- In_Left_Hand_Side --
      -----------------------

      function In_Left_Hand_Side (Comp : Node_Id) return Boolean is
      begin
         return (Nkind (Parent (Comp)) = N_Assignment_Statement
                  and then Comp = Name (Parent (Comp)))
           or else (Present (Parent (Comp))
                     and then Nkind (Parent (Comp)) in N_Subexpr
                     and then In_Left_Hand_Side (Parent (Comp)));
      end In_Left_Hand_Side;

      -----------------------------
      --  Is_Subtype_Declaration --
      -----------------------------

      function Is_Subtype_Declaration return Boolean is
         Par : constant Node_Id := Parent (N);
      begin
         return
           Nkind (Par) = N_Index_Or_Discriminant_Constraint
             and then Nkind (Parent (Parent (Par))) = N_Subtype_Declaration
             and then Comes_From_Source (Entity (Prefix (N)))
             and then Sloc (Par) = Sloc (Entity (Prefix (N)));
      end Is_Subtype_Declaration;

   --  Start of processing for Expand_N_Selected_Component

   begin
      --  Insert explicit dereference if required

      if Is_Access_Type (Ptyp) then

         --  First set prefix type to proper access type, in case it currently
         --  has a private (non-access) view of this type.

         Set_Etype (P, Ptyp);

         Insert_Explicit_Dereference (P);
         Analyze_And_Resolve (P, Designated_Type (Ptyp));

         Ptyp := Etype (P);
      end if;

      --  Deal with discriminant check required

      if Do_Discriminant_Check (N) then
         if Present (Discriminant_Checking_Func
                      (Original_Record_Component (Entity (S))))
         then
            --  Present the discriminant checking function to the backend, so
            --  that it can inline the call to the function.

            Add_Inlined_Body
              (Discriminant_Checking_Func
                (Original_Record_Component (Entity (S))),
               N);

            --  Now reset the flag and generate the call

            Set_Do_Discriminant_Check (N, False);
            Generate_Discriminant_Check (N);

         --  In the case of Unchecked_Union, no discriminant checking is
         --  actually performed.

         else
            Set_Do_Discriminant_Check (N, False);
         end if;
      end if;

      --  Ada 2005 (AI-318-02): If the prefix is a call to a build-in-place
      --  function, then additional actuals must be passed.

      if Is_Build_In_Place_Function_Call (P) then
         Make_Build_In_Place_Call_In_Anonymous_Context (P);

      --  Ada 2005 (AI-318-02): Specialization of the previous case for prefix
      --  containing build-in-place function calls whose returned object covers
      --  interface types.

      elsif Present (Unqual_BIP_Iface_Function_Call (P)) then
         Make_Build_In_Place_Iface_Call_In_Anonymous_Context (P);
      end if;

      --  Gigi cannot handle unchecked conversions that are the prefix of a
      --  selected component with discriminants. This must be checked during
      --  expansion, because during analysis the type of the selector is not
      --  known at the point the prefix is analyzed. If the conversion is the
      --  target of an assignment, then we cannot force the evaluation.

      if Nkind (Prefix (N)) = N_Unchecked_Type_Conversion
        and then Has_Discriminants (Etype (N))
        and then not In_Left_Hand_Side (N)
      then
         Force_Evaluation (Prefix (N));
      end if;

      --  Remaining processing applies only if selector is a discriminant

      if Ekind (Entity (Selector_Name (N))) = E_Discriminant then

         --  If the selector is a discriminant of a constrained record type,
         --  we may be able to rewrite the expression with the actual value
         --  of the discriminant, a useful optimization in some cases.

         if Is_Record_Type (Ptyp)
           and then Has_Discriminants (Ptyp)
           and then Is_Constrained (Ptyp)
         then
            --  Do this optimization for discrete types only, and not for
            --  access types (access discriminants get us into trouble).

            if not Is_Discrete_Type (Etype (N)) then
               null;

            --  Don't do this on the left-hand side of an assignment statement.
            --  Normally one would think that references like this would not
            --  occur, but they do in generated code, and mean that we really
            --  do want to assign the discriminant.

            elsif Nkind (Par) = N_Assignment_Statement
              and then Name (Par) = N
            then
               null;

            --  Don't do this optimization for the prefix of an attribute or
            --  the name of an object renaming declaration since these are
            --  contexts where we do not want the value anyway.

            elsif (Nkind (Par) = N_Attribute_Reference
                    and then Prefix (Par) = N)
              or else Is_Renamed_Object (N)
            then
               null;

            --  Don't do this optimization if we are within the code for a
            --  discriminant check, since the whole point of such a check may
            --  be to verify the condition on which the code below depends.

            elsif Is_In_Discriminant_Check (N) then
               null;

            --  Green light to see if we can do the optimization. There is
            --  still one condition that inhibits the optimization below but
            --  now is the time to check the particular discriminant.

            else
               --  Loop through discriminants to find the matching discriminant
               --  constraint to see if we can copy it.

               Disc := First_Discriminant (Ptyp);
               Dcon := First_Elmt (Discriminant_Constraint (Ptyp));
               Discr_Loop : while Present (Dcon) loop
                  Dval := Node (Dcon);

                  --  Check if this is the matching discriminant and if the
                  --  discriminant value is simple enough to make sense to
                  --  copy. We don't want to copy complex expressions, and
                  --  indeed to do so can cause trouble (before we put in
                  --  this guard, a discriminant expression containing an
                  --  AND THEN was copied, causing problems for coverage
                  --  analysis tools).

                  --  However, if the reference is part of the initialization
                  --  code generated for an object declaration, we must use
                  --  the discriminant value from the subtype constraint,
                  --  because the selected component may be a reference to the
                  --  object being initialized, whose discriminant is not yet
                  --  set. This only happens in complex cases involving changes
                  --  or representation.

                  if Disc = Entity (Selector_Name (N))
                    and then (Is_Entity_Name (Dval)
                               or else Compile_Time_Known_Value (Dval)
                               or else Is_Subtype_Declaration)
                  then
                     --  Here we have the matching discriminant. Check for
                     --  the case of a discriminant of a component that is
                     --  constrained by an outer discriminant, which cannot
                     --  be optimized away.

                     if Denotes_Discriminant
                          (Dval, Check_Concurrent => True)
                     then
                        exit Discr_Loop;

                     elsif Nkind (Original_Node (Dval)) = N_Selected_Component
                       and then
                         Denotes_Discriminant
                           (Selector_Name (Original_Node (Dval)), True)
                     then
                        exit Discr_Loop;

                     --  Do not retrieve value if constraint is not static. It
                     --  is generally not useful, and the constraint may be a
                     --  rewritten outer discriminant in which case it is in
                     --  fact incorrect.

                     elsif Is_Entity_Name (Dval)
                       and then
                         Nkind (Parent (Entity (Dval))) = N_Object_Declaration
                       and then Present (Expression (Parent (Entity (Dval))))
                       and then not
                         Is_OK_Static_Expression
                           (Expression (Parent (Entity (Dval))))
                     then
                        exit Discr_Loop;

                     --  In the context of a case statement, the expression may
                     --  have the base type of the discriminant, and we need to
                     --  preserve the constraint to avoid spurious errors on
                     --  missing cases.

                     elsif Nkind (Parent (N)) = N_Case_Statement
                       and then Etype (Dval) /= Etype (Disc)
                     then
                        Rewrite (N,
                          Make_Qualified_Expression (Loc,
                            Subtype_Mark =>
                              New_Occurrence_Of (Etype (Disc), Loc),
                            Expression   =>
                              New_Copy_Tree (Dval)));
                        Analyze_And_Resolve (N, Etype (Disc));

                        --  In case that comes out as a static expression,
                        --  reset it (a selected component is never static).

                        Set_Is_Static_Expression (N, False);
                        return;

                     --  Otherwise we can just copy the constraint, but the
                     --  result is certainly not static. In some cases the
                     --  discriminant constraint has been analyzed in the
                     --  context of the original subtype indication, but for
                     --  itypes the constraint might not have been analyzed
                     --  yet, and this must be done now.

                     else
                        Rewrite (N, New_Copy_Tree (Dval));
                        Analyze_And_Resolve (N);
                        Set_Is_Static_Expression (N, False);
                        return;
                     end if;
                  end if;

                  Next_Elmt (Dcon);
                  Next_Discriminant (Disc);
               end loop Discr_Loop;

               --  Note: the above loop should always find a matching
               --  discriminant, but if it does not, we just missed an
               --  optimization due to some glitch (perhaps a previous
               --  error), so ignore.

            end if;
         end if;

         --  The only remaining processing is in the case of a discriminant of
         --  a concurrent object, where we rewrite the prefix to denote the
         --  corresponding record type. If the type is derived and has renamed
         --  discriminants, use corresponding discriminant, which is the one
         --  that appears in the corresponding record.

         if not Is_Concurrent_Type (Ptyp) then
            return;
         end if;

         Disc := Entity (Selector_Name (N));

         if Is_Derived_Type (Ptyp)
           and then Present (Corresponding_Discriminant (Disc))
         then
            Disc := Corresponding_Discriminant (Disc);
         end if;

         New_N :=
           Make_Selected_Component (Loc,
             Prefix =>
               Unchecked_Convert_To (Corresponding_Record_Type (Ptyp),
                 New_Copy_Tree (P)),
             Selector_Name => Make_Identifier (Loc, Chars (Disc)));

         Rewrite (N, New_N);
         Analyze (N);
      end if;

      --  Set Atomic_Sync_Required if necessary for atomic component

      if Nkind (N) = N_Selected_Component then
         declare
            E   : constant Entity_Id := Entity (Selector_Name (N));
            Set : Boolean;

         begin
            --  If component is atomic, but type is not, setting depends on
            --  disable/enable state for the component.

            if Is_Atomic (E) and then not Is_Atomic (Etype (E)) then
               Set := not Atomic_Synchronization_Disabled (E);

            --  If component is not atomic, but its type is atomic, setting
            --  depends on disable/enable state for the type.

            elsif not Is_Atomic (E) and then Is_Atomic (Etype (E)) then
               Set := not Atomic_Synchronization_Disabled (Etype (E));

            --  If both component and type are atomic, we disable if either
            --  component or its type have sync disabled.

            elsif Is_Atomic (E) and then Is_Atomic (Etype (E)) then
               Set := (not Atomic_Synchronization_Disabled (E))
                        and then
                      (not Atomic_Synchronization_Disabled (Etype (E)));

            else
               Set := False;
            end if;

            --  Set flag if required

            if Set then
               Activate_Atomic_Synchronization (N);
            end if;
         end;
      end if;
   end Expand_N_Selected_Component;

   --------------------
   -- Expand_N_Slice --
   --------------------

   procedure Expand_N_Slice (N : Node_Id) is
      Loc : constant Source_Ptr := Sloc (N);
      Typ : constant Entity_Id  := Etype (N);

      function Is_Procedure_Actual (N : Node_Id) return Boolean;
      --  Check whether the argument is an actual for a procedure call, in
      --  which case the expansion of a bit-packed slice is deferred until the
      --  call itself is expanded. The reason this is required is that we might
      --  have an IN OUT or OUT parameter, and the copy out is essential, and
      --  that copy out would be missed if we created a temporary here in
      --  Expand_N_Slice. Note that we don't bother to test specifically for an
      --  IN OUT or OUT mode parameter, since it is a bit tricky to do, and it
      --  is harmless to defer expansion in the IN case, since the call
      --  processing will still generate the appropriate copy in operation,
      --  which will take care of the slice.

      procedure Make_Temporary_For_Slice;
      --  Create a named variable for the value of the slice, in cases where
      --  the back end cannot handle it properly, e.g. when packed types or
      --  unaligned slices are involved.

      -------------------------
      -- Is_Procedure_Actual --
      -------------------------

      function Is_Procedure_Actual (N : Node_Id) return Boolean is
         Par : Node_Id := Parent (N);

      begin
         loop
            --  If our parent is a procedure call we can return

            if Nkind (Par) = N_Procedure_Call_Statement then
               return True;

            --  If our parent is a type conversion, keep climbing the tree,
            --  since a type conversion can be a procedure actual. Also keep
            --  climbing if parameter association or a qualified expression,
            --  since these are additional cases that do can appear on
            --  procedure actuals.

            elsif Nkind_In (Par, N_Type_Conversion,
                                 N_Parameter_Association,
                                 N_Qualified_Expression)
            then
               Par := Parent (Par);

               --  Any other case is not what we are looking for

            else
               return False;
            end if;
         end loop;
      end Is_Procedure_Actual;

      ------------------------------
      -- Make_Temporary_For_Slice --
      ------------------------------

      procedure Make_Temporary_For_Slice is
         Ent  : constant Entity_Id := Make_Temporary (Loc, 'T', N);
         Decl : Node_Id;

      begin
         Decl :=
           Make_Object_Declaration (Loc,
             Defining_Identifier => Ent,
             Object_Definition   => New_Occurrence_Of (Typ, Loc));

         Set_No_Initialization (Decl);

         Insert_Actions (N, New_List (
           Decl,
           Make_Assignment_Statement (Loc,
             Name       => New_Occurrence_Of (Ent, Loc),
             Expression => Relocate_Node (N))));

         Rewrite (N, New_Occurrence_Of (Ent, Loc));
         Analyze_And_Resolve (N, Typ);
      end Make_Temporary_For_Slice;

      --  Local variables

      Pref     : constant Node_Id := Prefix (N);
      Pref_Typ : Entity_Id        := Etype (Pref);

   --  Start of processing for Expand_N_Slice

   begin
      --  Special handling for access types

      if Is_Access_Type (Pref_Typ) then
         Pref_Typ := Designated_Type (Pref_Typ);

         Rewrite (Pref,
           Make_Explicit_Dereference (Sloc (N),
            Prefix => Relocate_Node (Pref)));

         Analyze_And_Resolve (Pref, Pref_Typ);
      end if;

      --  Ada 2005 (AI-318-02): If the prefix is a call to a build-in-place
      --  function, then additional actuals must be passed.

      if Is_Build_In_Place_Function_Call (Pref) then
         Make_Build_In_Place_Call_In_Anonymous_Context (Pref);

      --  Ada 2005 (AI-318-02): Specialization of the previous case for prefix
      --  containing build-in-place function calls whose returned object covers
      --  interface types.

      elsif Present (Unqual_BIP_Iface_Function_Call (Pref)) then
         Make_Build_In_Place_Iface_Call_In_Anonymous_Context (Pref);
      end if;

      --  The remaining case to be handled is packed slices. We can leave
      --  packed slices as they are in the following situations:

      --    1. Right or left side of an assignment (we can handle this
      --       situation correctly in the assignment statement expansion).

      --    2. Prefix of indexed component (the slide is optimized away in this
      --       case, see the start of Expand_N_Slice.)

      --    3. Object renaming declaration, since we want the name of the
      --       slice, not the value.

      --    4. Argument to procedure call, since copy-in/copy-out handling may
      --       be required, and this is handled in the expansion of call
      --       itself.

      --    5. Prefix of an address attribute (this is an error which is caught
      --       elsewhere, and the expansion would interfere with generating the
      --       error message) or of a size attribute (because 'Size may change
      --       when applied to the temporary instead of the slice directly).

      if not Is_Packed (Typ) then

         --  Apply transformation for actuals of a function call, where
         --  Expand_Actuals is not used.

         if Nkind (Parent (N)) = N_Function_Call
           and then Is_Possibly_Unaligned_Slice (N)
         then
            Make_Temporary_For_Slice;
         end if;

      elsif Nkind (Parent (N)) = N_Assignment_Statement
        or else (Nkind (Parent (Parent (N))) = N_Assignment_Statement
                  and then Parent (N) = Name (Parent (Parent (N))))
      then
         return;

      elsif Nkind (Parent (N)) = N_Indexed_Component
        or else Is_Renamed_Object (N)
        or else Is_Procedure_Actual (N)
      then
         return;

      elsif Nkind (Parent (N)) = N_Attribute_Reference
        and then (Attribute_Name (Parent (N)) = Name_Address
                   or else Attribute_Name (Parent (N)) = Name_Size)
      then
         return;

      else
         Make_Temporary_For_Slice;
      end if;
   end Expand_N_Slice;

   ------------------------------
   -- Expand_N_Type_Conversion --
   ------------------------------

   procedure Expand_N_Type_Conversion (N : Node_Id) is
      Loc          : constant Source_Ptr := Sloc (N);
      Operand      : constant Node_Id    := Expression (N);
      Operand_Acc  : Node_Id             := Operand;
      Target_Type  : Entity_Id           := Etype (N);
      Operand_Type : Entity_Id           := Etype (Operand);

      procedure Discrete_Range_Check;
      --  Handles generation of range check for discrete target value

      procedure Handle_Changed_Representation;
      --  This is called in the case of record and array type conversions to
      --  see if there is a change of representation to be handled. Change of
      --  representation is actually handled at the assignment statement level,
      --  and what this procedure does is rewrite node N conversion as an
      --  assignment to temporary. If there is no change of representation,
      --  then the conversion node is unchanged.

      procedure Raise_Accessibility_Error;
      --  Called when we know that an accessibility check will fail. Rewrites
      --  node N to an appropriate raise statement and outputs warning msgs.
      --  The Etype of the raise node is set to Target_Type. Note that in this
      --  case the rest of the processing should be skipped (i.e. the call to
      --  this procedure will be followed by "goto Done").

      procedure Real_Range_Check;
      --  Handles generation of range check for real target value

      function Has_Extra_Accessibility (Id : Entity_Id) return Boolean;
      --  True iff Present (Effective_Extra_Accessibility (Id)) successfully
      --  evaluates to True.

      --------------------------
      -- Discrete_Range_Check --
      --------------------------

      --  Case of conversions to a discrete type. We let Generate_Range_Check
      --  do the heavy lifting, after converting a fixed-point operand to an
      --  appropriate integer type.

      procedure Discrete_Range_Check is
         Expr : Node_Id;
         Ityp : Entity_Id;

      begin
         --  Nothing to do if conversion was rewritten

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

         Expr := Expression (N);

         --  Nothing to do if range checks suppressed

         if Range_Checks_Suppressed (Target_Type) then
            return;
         end if;

         --  Nothing to do if expression is an entity on which checks have been
         --  suppressed.

         if Is_Entity_Name (Expr)
           and then Range_Checks_Suppressed (Entity (Expr))
         then
            return;
         end if;

         --  Before we do a range check, we have to deal with treating
         --  a fixed-point operand as an integer. The way we do this
         --  is simply to do an unchecked conversion to an appropriate
         --  integer type large enough to hold the result.

         if Is_Fixed_Point_Type (Etype (Expr)) then
            if Esize (Base_Type (Etype (Expr))) > Esize (Standard_Integer) then
               Ityp := Standard_Long_Long_Integer;
            else
               Ityp := Standard_Integer;
            end if;

            Set_Do_Range_Check (Expr, False);
            Rewrite (Expr, Unchecked_Convert_To (Ityp, Expr));
         end if;

         --  Reset overflow flag, since the range check will include
         --  dealing with possible overflow, and generate the check.

         Set_Do_Overflow_Check (N, False);

         Generate_Range_Check (Expr, Target_Type, CE_Range_Check_Failed);
      end Discrete_Range_Check;

      -----------------------------------
      -- Handle_Changed_Representation --
      -----------------------------------

      procedure Handle_Changed_Representation is
         Temp : Entity_Id;
         Decl : Node_Id;
         Odef : Node_Id;
         N_Ix : Node_Id;
         Cons : List_Id;

      begin
         --  Nothing else to do if no change of representation

         if Same_Representation (Operand_Type, Target_Type) then
            return;

         --  The real change of representation work is done by the assignment
         --  statement processing. So if this type conversion is appearing as
         --  the expression of an assignment statement, nothing needs to be
         --  done to the conversion.

         elsif Nkind (Parent (N)) = N_Assignment_Statement then
            return;

         --  Otherwise we need to generate a temporary variable, and do the
         --  change of representation assignment into that temporary variable.
         --  The conversion is then replaced by a reference to this variable.

         else
            Cons := No_List;

            --  If type is unconstrained we have to add a constraint, copied
            --  from the actual value of the left-hand side.

            if not Is_Constrained (Target_Type) then
               if Has_Discriminants (Operand_Type) then

                  --  A change of representation can only apply to untagged
                  --  types. We need to build the constraint that applies to
                  --  the target type, using the constraints of the operand.
                  --  The analysis is complicated if there are both inherited
                  --  discriminants and constrained discriminants.
                  --  We iterate over the discriminants of the target, and
                  --  find the discriminant of the same name:

                  --  a) If there is a corresponding discriminant in the object
                  --  then the value is a selected component of the operand.

                  --  b) Otherwise the value of a constrained discriminant is
                  --  found in the stored constraint of the operand.

                  declare
                     Stored : constant Elist_Id :=
                                Stored_Constraint (Operand_Type);

                     Elmt : Elmt_Id;

                     Disc_O : Entity_Id;
                     --  Discriminant of the operand type. Its value in the
                     --  object is captured in a selected component.

                     Disc_S : Entity_Id;
                     --  Stored discriminant of the operand. If present, it
                     --  corresponds to a constrained discriminant of the
                     --  parent type.

                     Disc_T : Entity_Id;
                     --  Discriminant of the target type

                  begin
                     Disc_T := First_Discriminant (Target_Type);
                     Disc_O := First_Discriminant (Operand_Type);
                     Disc_S := First_Stored_Discriminant (Operand_Type);

                     if Present (Stored) then
                        Elmt := First_Elmt (Stored);
                     else
                        Elmt := No_Elmt; -- init to avoid warning
                     end if;

                     Cons := New_List;
                     while Present (Disc_T) loop
                        if Present (Disc_O)
                          and then Chars (Disc_T) = Chars (Disc_O)
                        then
                           Append_To (Cons,
                             Make_Selected_Component (Loc,
                               Prefix        =>
                                 Duplicate_Subexpr_Move_Checks (Operand),
                               Selector_Name =>
                                 Make_Identifier (Loc, Chars (Disc_O))));
                           Next_Discriminant (Disc_O);

                        elsif Present (Disc_S) then
                           Append_To (Cons, New_Copy_Tree (Node (Elmt)));
                           Next_Elmt (Elmt);
                        end if;

                        Next_Discriminant (Disc_T);
                     end loop;
                  end;

               elsif Is_Array_Type (Operand_Type) then
                  N_Ix := First_Index (Target_Type);
                  Cons := New_List;

                  for J in 1 .. Number_Dimensions (Operand_Type) loop

                     --  We convert the bounds explicitly. We use an unchecked
                     --  conversion because bounds checks are done elsewhere.

                     Append_To (Cons,
                       Make_Range (Loc,
                         Low_Bound  =>
                           Unchecked_Convert_To (Etype (N_Ix),
                             Make_Attribute_Reference (Loc,
                               Prefix         =>
                                 Duplicate_Subexpr_No_Checks
                                   (Operand, Name_Req => True),
                               Attribute_Name => Name_First,
                               Expressions    => New_List (
                                 Make_Integer_Literal (Loc, J)))),

                         High_Bound =>
                           Unchecked_Convert_To (Etype (N_Ix),
                             Make_Attribute_Reference (Loc,
                               Prefix         =>
                                 Duplicate_Subexpr_No_Checks
                                   (Operand, Name_Req => True),
                               Attribute_Name => Name_Last,
                               Expressions    => New_List (
                                 Make_Integer_Literal (Loc, J))))));

                     Next_Index (N_Ix);
                  end loop;
               end if;
            end if;

            Odef := New_Occurrence_Of (Target_Type, Loc);

            if Present (Cons) then
               Odef :=
                 Make_Subtype_Indication (Loc,
                   Subtype_Mark => Odef,
                   Constraint   =>
                     Make_Index_Or_Discriminant_Constraint (Loc,
                       Constraints => Cons));
            end if;

            Temp := Make_Temporary (Loc, 'C');
            Decl :=
              Make_Object_Declaration (Loc,
                Defining_Identifier => Temp,
                Object_Definition   => Odef);

            Set_No_Initialization (Decl, True);

            --  Insert required actions. It is essential to suppress checks
            --  since we have suppressed default initialization, which means
            --  that the variable we create may have no discriminants.

            Insert_Actions (N,
              New_List (
                Decl,
                Make_Assignment_Statement (Loc,
                  Name       => New_Occurrence_Of (Temp, Loc),
                  Expression => Relocate_Node (N))),
                Suppress => All_Checks);

            Rewrite (N, New_Occurrence_Of (Temp, Loc));
            return;
         end if;
      end Handle_Changed_Representation;

      -------------------------------
      -- Raise_Accessibility_Error --
      -------------------------------

      procedure Raise_Accessibility_Error is
      begin
         Error_Msg_Warn := SPARK_Mode /= On;
         Rewrite (N,
           Make_Raise_Program_Error (Sloc (N),
             Reason => PE_Accessibility_Check_Failed));
         Set_Etype (N, Target_Type);

         Error_Msg_N ("<<accessibility check failure", N);
         Error_Msg_NE ("\<<& [", N, Standard_Program_Error);
      end Raise_Accessibility_Error;

      ----------------------
      -- Real_Range_Check --
      ----------------------

      --  Case of conversions to floating-point or fixed-point. If range checks
      --  are enabled and the target type has a range constraint, we convert:

      --     typ (x)

      --       to

      --     Tnn : typ'Base := typ'Base (x);
      --     [constraint_error when Tnn < typ'First or else Tnn > typ'Last]
      --     typ (Tnn)

      --  This is necessary when there is a conversion of integer to float or
      --  to fixed-point to ensure that the correct checks are made. It is not
      --  necessary for the float-to-float case where it is enough to just set
      --  the Do_Range_Check flag on the expression.

      procedure Real_Range_Check is
         Btyp : constant Entity_Id := Base_Type (Target_Type);
         Lo   : constant Node_Id   := Type_Low_Bound  (Target_Type);
         Hi   : constant Node_Id   := Type_High_Bound (Target_Type);

         Conv   : Node_Id;
         Hi_Arg : Node_Id;
         Hi_Val : Node_Id;
         Lo_Arg : Node_Id;
         Lo_Val : Node_Id;
         Expr   : Entity_Id;
         Tnn    : Entity_Id;

      begin
         --  Nothing to do if conversion was rewritten

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

         Expr := Expression (N);

         --  Clear the flag once for all

         Set_Do_Range_Check (Expr, False);

         --  Nothing to do if range checks suppressed, or target has the same
         --  range as the base type (or is the base type).

         if Range_Checks_Suppressed (Target_Type)
           or else (Lo = Type_Low_Bound  (Btyp)
                      and then
                    Hi = Type_High_Bound (Btyp))
         then
            return;
         end if;

         --  Nothing to do if expression is an entity on which checks have been
         --  suppressed.

         if Is_Entity_Name (Expr)
           and then Range_Checks_Suppressed (Entity (Expr))
         then
            return;
         end if;

         --  Nothing to do if expression was rewritten into a float-to-float
         --  conversion, since this kind of conversion is handled elsewhere.

         if Is_Floating_Point_Type (Etype (Expr))
           and then Is_Floating_Point_Type (Target_Type)
         then
            return;
         end if;

         --  Nothing to do if bounds are all static and we can tell that the
         --  expression is within the bounds of the target. Note that if the
         --  operand is of an unconstrained floating-point type, then we do
         --  not trust it to be in range (might be infinite)

         declare
            S_Lo : constant Node_Id := Type_Low_Bound (Etype (Expr));
            S_Hi : constant Node_Id := Type_High_Bound (Etype (Expr));

         begin
            if (not Is_Floating_Point_Type (Etype (Expr))
                 or else Is_Constrained (Etype (Expr)))
              and then Compile_Time_Known_Value (S_Lo)
              and then Compile_Time_Known_Value (S_Hi)
              and then Compile_Time_Known_Value (Hi)
              and then Compile_Time_Known_Value (Lo)
            then
               declare
                  D_Lov : constant Ureal := Expr_Value_R (Lo);
                  D_Hiv : constant Ureal := Expr_Value_R (Hi);
                  S_Lov : Ureal;
                  S_Hiv : Ureal;

               begin
                  if Is_Real_Type (Etype (Expr)) then
                     S_Lov := Expr_Value_R (S_Lo);
                     S_Hiv := Expr_Value_R (S_Hi);
                  else
                     S_Lov := UR_From_Uint (Expr_Value (S_Lo));
                     S_Hiv := UR_From_Uint (Expr_Value (S_Hi));
                  end if;

                  if D_Hiv > D_Lov
                    and then S_Lov >= D_Lov
                    and then S_Hiv <= D_Hiv
                  then
                     return;
                  end if;
               end;
            end if;
         end;

         --  Otherwise rewrite the conversion as described above

         Conv := Convert_To (Btyp, Expr);

         --  If a conversion is necessary, then copy the specific flags from
         --  the original one and also move the Do_Overflow_Check flag since
         --  this new conversion is to the base type.

         if Nkind (Conv) = N_Type_Conversion then
            Set_Conversion_OK  (Conv, Conversion_OK  (N));
            Set_Float_Truncate (Conv, Float_Truncate (N));
            Set_Rounded_Result (Conv, Rounded_Result (N));

            if Do_Overflow_Check (N) then
               Set_Do_Overflow_Check (Conv);
               Set_Do_Overflow_Check (N, False);
            end if;
         end if;

         Tnn := Make_Temporary (Loc, 'T', Conv);

         --  For a conversion from Float to Fixed where the bounds of the
         --  fixed-point type are static, we can obtain a more accurate
         --  fixed-point value by converting the result of the floating-
         --  point expression to an appropriate integer type, and then
         --  performing an unchecked conversion to the target fixed-point
         --  type. The range check can then use the corresponding integer
         --  value of the bounds instead of requiring further conversions.
         --  This preserves the identity:

         --        Fix_Val = Fixed_Type (Float_Type (Fix_Val))

         --  which used to fail when Fix_Val was a bound of the type and
         --  the 'Small was not a representable number.
         --  This transformation requires an integer type large enough to
         --  accommodate a fixed-point value. This will not be the case
         --  in systems where Duration is larger than Long_Integer.

         if Is_Ordinary_Fixed_Point_Type (Target_Type)
           and then Is_Floating_Point_Type (Etype (Expr))
           and then RM_Size (Btyp) <= RM_Size (Standard_Long_Integer)
           and then Nkind (Lo) = N_Real_Literal
           and then Nkind (Hi) = N_Real_Literal
         then
            declare
               Expr_Id : constant Entity_Id := Make_Temporary (Loc, 'T', Conv);
               Int_Type : Entity_Id;

            begin
               --  Find an integer type of the appropriate size to perform an
               --  unchecked conversion to the target fixed-point type.

               if RM_Size (Btyp) > RM_Size (Standard_Integer) then
                  Int_Type := Standard_Long_Integer;

               elsif RM_Size (Btyp) > RM_Size (Standard_Short_Integer) then
                  Int_Type := Standard_Integer;

               else
                  Int_Type := Standard_Short_Integer;
               end if;

               --  Generate a temporary with the integer value. Required in the
               --  CCG compiler to ensure that run-time checks reference this
               --  integer expression (instead of the resulting fixed-point
               --  value because fixed-point values are handled by means of
               --  unsigned integer types).

               Insert_Action (N,
                 Make_Object_Declaration (Loc,
                   Defining_Identifier => Expr_Id,
                   Object_Definition   => New_Occurrence_Of (Int_Type, Loc),
                   Constant_Present    => True,
                   Expression          =>
                     Convert_To (Int_Type, Expression (Conv))));

               --  Create integer objects for range checking of result.

               Lo_Arg :=
                 Unchecked_Convert_To
                   (Int_Type, New_Occurrence_Of (Expr_Id, Loc));

               Lo_Val :=
                 Make_Integer_Literal (Loc, Corresponding_Integer_Value (Lo));

               Hi_Arg :=
                 Unchecked_Convert_To
                   (Int_Type, New_Occurrence_Of (Expr_Id, Loc));

               Hi_Val :=
                 Make_Integer_Literal (Loc, Corresponding_Integer_Value (Hi));

               --  Rewrite conversion as an integer conversion of the
               --  original floating-point expression, followed by an
               --  unchecked conversion to the target fixed-point type.

               Conv :=
                 Make_Unchecked_Type_Conversion (Loc,
                   Subtype_Mark => New_Occurrence_Of (Target_Type, Loc),
                   Expression   => New_Occurrence_Of (Expr_Id, Loc));
            end;

         --  All other conversions

         else
            Lo_Arg := New_Occurrence_Of (Tnn, Loc);
            Lo_Val :=
              Make_Attribute_Reference (Loc,
                Prefix         => New_Occurrence_Of (Target_Type, Loc),
                Attribute_Name => Name_First);

            Hi_Arg := New_Occurrence_Of (Tnn, Loc);
            Hi_Val :=
              Make_Attribute_Reference (Loc,
                Prefix         => New_Occurrence_Of (Target_Type, Loc),
                Attribute_Name => Name_Last);
         end if;

         --  Build code for range checking. Note that checks are suppressed
         --  here since we don't want a recursive range check popping up.

         Insert_Actions (N, New_List (
           Make_Object_Declaration (Loc,
             Defining_Identifier => Tnn,
             Object_Definition   => New_Occurrence_Of (Btyp, Loc),
             Constant_Present    => True,
             Expression          => Conv),

           Make_Raise_Constraint_Error (Loc,
             Condition =>
               Make_Or_Else (Loc,
                 Left_Opnd  =>
                   Make_Op_Lt (Loc,
                     Left_Opnd  => Lo_Arg,
                     Right_Opnd => Lo_Val),

                Right_Opnd =>
                  Make_Op_Gt (Loc,
                    Left_Opnd  => Hi_Arg,
                    Right_Opnd => Hi_Val)),
              Reason   => CE_Range_Check_Failed)),
           Suppress => All_Checks);

         Rewrite (Expr, New_Occurrence_Of (Tnn, Loc));
      end Real_Range_Check;

      -----------------------------
      -- Has_Extra_Accessibility --
      -----------------------------

      --  Returns true for a formal of an anonymous access type or for an Ada
      --  2012-style stand-alone object of an anonymous access type.

      function Has_Extra_Accessibility (Id : Entity_Id) return Boolean is
      begin
         if Is_Formal (Id) or else Ekind_In (Id, E_Constant, E_Variable) then
            return Present (Effective_Extra_Accessibility (Id));
         else
            return False;
         end if;
      end Has_Extra_Accessibility;

   --  Start of processing for Expand_N_Type_Conversion

   begin
      --  First remove check marks put by the semantic analysis on the type
      --  conversion between array types. We need these checks, and they will
      --  be generated by this expansion routine, but we do not depend on these
      --  flags being set, and since we do intend to expand the checks in the
      --  front end, we don't want them on the tree passed to the back end.

      if Is_Array_Type (Target_Type) then
         if Is_Constrained (Target_Type) then
            Set_Do_Length_Check (N, False);
         else
            Set_Do_Range_Check (Operand, False);
         end if;
      end if;

      --  Nothing at all to do if conversion is to the identical type so remove
      --  the conversion completely, it is useless, except that it may carry
      --  an Assignment_OK attribute, which must be propagated to the operand.

      if Operand_Type = Target_Type then
         if Assignment_OK (N) then
            Set_Assignment_OK (Operand);
         end if;

         Rewrite (N, Relocate_Node (Operand));
         goto Done;
      end if;

      --  Nothing to do if this is the second argument of read. This is a
      --  "backwards" conversion that will be handled by the specialized code
      --  in attribute processing.

      if Nkind (Parent (N)) = N_Attribute_Reference
        and then Attribute_Name (Parent (N)) = Name_Read
        and then Next (First (Expressions (Parent (N)))) = N
      then
         goto Done;
      end if;

      --  Check for case of converting to a type that has an invariant
      --  associated with it. This requires an invariant check. We insert
      --  a call:

      --        invariant_check (typ (expr))

      --  in the code, after removing side effects from the expression.
      --  This is clearer than replacing the conversion into an expression
      --  with actions, because the context may impose additional actions
      --  (tag checks, membership tests, etc.) that conflict with this
      --  rewriting (used previously).

      --  Note: the Comes_From_Source check, and then the resetting of this
      --  flag prevents what would otherwise be an infinite recursion.

      if Has_Invariants (Target_Type)
        and then Present (Invariant_Procedure (Target_Type))
        and then Comes_From_Source (N)
      then
         Set_Comes_From_Source (N, False);
         Remove_Side_Effects (N);
         Insert_Action (N, Make_Invariant_Call (Duplicate_Subexpr (N)));
         goto Done;
      end if;

      --  Here if we may need to expand conversion

      --  If the operand of the type conversion is an arithmetic operation on
      --  signed integers, and the based type of the signed integer type in
      --  question is smaller than Standard.Integer, we promote both of the
      --  operands to type Integer.

      --  For example, if we have

      --     target-type (opnd1 + opnd2)

      --  and opnd1 and opnd2 are of type short integer, then we rewrite
      --  this as:

      --     target-type (integer(opnd1) + integer(opnd2))

      --  We do this because we are always allowed to compute in a larger type
      --  if we do the right thing with the result, and in this case we are
      --  going to do a conversion which will do an appropriate check to make
      --  sure that things are in range of the target type in any case. This
      --  avoids some unnecessary intermediate overflows.

      --  We might consider a similar transformation in the case where the
      --  target is a real type or a 64-bit integer type, and the operand
      --  is an arithmetic operation using a 32-bit integer type. However,
      --  we do not bother with this case, because it could cause significant
      --  inefficiencies on 32-bit machines. On a 64-bit machine it would be
      --  much cheaper, but we don't want different behavior on 32-bit and
      --  64-bit machines. Note that the exclusion of the 64-bit case also
      --  handles the configurable run-time cases where 64-bit arithmetic
      --  may simply be unavailable.

      --  Note: this circuit is partially redundant with respect to the circuit
      --  in Checks.Apply_Arithmetic_Overflow_Check, but we catch more cases in
      --  the processing here. Also we still need the Checks circuit, since we
      --  have to be sure not to generate junk overflow checks in the first
      --  place, since it would be trick to remove them here.

      if Integer_Promotion_Possible (N) then

         --  All conditions met, go ahead with transformation

         declare
            Opnd : Node_Id;
            L, R : Node_Id;

         begin
            R :=
              Make_Type_Conversion (Loc,
                Subtype_Mark => New_Occurrence_Of (Standard_Integer, Loc),
                Expression   => Relocate_Node (Right_Opnd (Operand)));

            Opnd := New_Op_Node (Nkind (Operand), Loc);
            Set_Right_Opnd (Opnd, R);

            if Nkind (Operand) in N_Binary_Op then
               L :=
                 Make_Type_Conversion (Loc,
                   Subtype_Mark => New_Occurrence_Of (Standard_Integer, Loc),
                   Expression   => Relocate_Node (Left_Opnd (Operand)));

               Set_Left_Opnd  (Opnd, L);
            end if;

            Rewrite (N,
              Make_Type_Conversion (Loc,
                Subtype_Mark => Relocate_Node (Subtype_Mark (N)),
                Expression   => Opnd));

            Analyze_And_Resolve (N, Target_Type);
            goto Done;
         end;
      end if;

      --  Do validity check if validity checking operands

      if Validity_Checks_On and Validity_Check_Operands then
         Ensure_Valid (Operand);
      end if;

      --  Special case of converting from non-standard boolean type

      if Is_Boolean_Type (Operand_Type)
        and then (Nonzero_Is_True (Operand_Type))
      then
         Adjust_Condition (Operand);
         Set_Etype (Operand, Standard_Boolean);
         Operand_Type := Standard_Boolean;
      end if;

      --  Case of converting to an access type

      if Is_Access_Type (Target_Type) then
         --  In terms of accessibility rules, an anonymous access discriminant
         --  is not considered separate from its parent object.

         if Nkind (Operand) = N_Selected_Component
           and then Ekind (Entity (Selector_Name (Operand))) = E_Discriminant
           and then Ekind (Operand_Type) = E_Anonymous_Access_Type
         then
            Operand_Acc := Original_Node (Prefix (Operand));
         end if;

         --  If this type conversion was internally generated by the front end
         --  to displace the pointer to the object to reference an interface
         --  type and the original node was an Unrestricted_Access attribute,
         --  then skip applying accessibility checks (because, according to the
         --  GNAT Reference Manual, this attribute is similar to 'Access except
         --  that all accessibility and aliased view checks are omitted).

         if not Comes_From_Source (N)
           and then Is_Interface (Designated_Type (Target_Type))
           and then Nkind (Original_Node (N)) = N_Attribute_Reference
           and then Attribute_Name (Original_Node (N)) =
                      Name_Unrestricted_Access
         then
            null;

         --  Apply an accessibility check when the conversion operand is an
         --  access parameter (or a renaming thereof), unless conversion was
         --  expanded from an Unchecked_ or Unrestricted_Access attribute,
         --  or for the actual of a class-wide interface parameter. Note that
         --  other checks may still need to be applied below (such as tagged
         --  type checks).

         elsif Is_Entity_Name (Operand_Acc)
           and then Has_Extra_Accessibility (Entity (Operand_Acc))
           and then Ekind (Etype (Operand_Acc)) = E_Anonymous_Access_Type
           and then (Nkind (Original_Node (N)) /= N_Attribute_Reference
                      or else Attribute_Name (Original_Node (N)) = Name_Access)
         then
            if not Comes_From_Source (N)
              and then Nkind_In (Parent (N), N_Function_Call,
                                             N_Parameter_Association,
                                             N_Procedure_Call_Statement)
              and then Is_Interface (Designated_Type (Target_Type))
              and then Is_Class_Wide_Type (Designated_Type (Target_Type))
            then
               null;

            else
               Apply_Accessibility_Check
                 (Operand_Acc, Target_Type, Insert_Node => Operand);
            end if;

         --  If the level of the operand type is statically deeper than the
         --  level of the target type, then force Program_Error. Note that this
         --  can only occur for cases where the attribute is within the body of
         --  an instantiation, otherwise the conversion will already have been
         --  rejected as illegal.

         --  Note: warnings are issued by the analyzer for the instance cases

         elsif In_Instance_Body

           --  The case where the target type is an anonymous access type of
           --  a discriminant is excluded, because the level of such a type
           --  depends on the context and currently the level returned for such
           --  types is zero, resulting in warnings about check failures
           --  in certain legal cases involving class-wide interfaces as the
           --  designated type (some cases, such as return statements, are
           --  checked at run time, but not clear if these are handled right
           --  in general, see 3.10.2(12/2-12.5/3) ???).

           and then
             not (Ekind (Target_Type) = E_Anonymous_Access_Type
                   and then Present (Associated_Node_For_Itype (Target_Type))
                   and then Nkind (Associated_Node_For_Itype (Target_Type)) =
                                                  N_Discriminant_Specification)
           and then
             Type_Access_Level (Operand_Type) > Type_Access_Level (Target_Type)
         then
            Raise_Accessibility_Error;
            goto Done;

         --  When the operand is a selected access discriminant the check needs
         --  to be made against the level of the object denoted by the prefix
         --  of the selected name. Force Program_Error for this case as well
         --  (this accessibility violation can only happen if within the body
         --  of an instantiation).

         elsif In_Instance_Body
           and then Ekind (Operand_Type) = E_Anonymous_Access_Type
           and then Nkind (Operand) = N_Selected_Component
           and then Ekind (Entity (Selector_Name (Operand))) = E_Discriminant
           and then Object_Access_Level (Operand) >
                      Type_Access_Level (Target_Type)
         then
            Raise_Accessibility_Error;
            goto Done;
         end if;
      end if;

      --  Case of conversions of tagged types and access to tagged types

      --  When needed, that is to say when the expression is class-wide, Add
      --  runtime a tag check for (strict) downward conversion by using the
      --  membership test, generating:

      --      [constraint_error when Operand not in Target_Type'Class]

      --  or in the access type case

      --      [constraint_error
      --        when Operand /= null
      --          and then Operand.all not in
      --            Designated_Type (Target_Type)'Class]

      if (Is_Access_Type (Target_Type)
           and then Is_Tagged_Type (Designated_Type (Target_Type)))
        or else Is_Tagged_Type (Target_Type)
      then
         --  Do not do any expansion in the access type case if the parent is a
         --  renaming, since this is an error situation which will be caught by
         --  Sem_Ch8, and the expansion can interfere with this error check.

         if Is_Access_Type (Target_Type) and then Is_Renamed_Object (N) then
            goto Done;
         end if;

         --  Otherwise, proceed with processing tagged conversion

         Tagged_Conversion : declare
            Actual_Op_Typ   : Entity_Id;
            Actual_Targ_Typ : Entity_Id;
            Make_Conversion : Boolean := False;
            Root_Op_Typ     : Entity_Id;

            procedure Make_Tag_Check (Targ_Typ : Entity_Id);
            --  Create a membership check to test whether Operand is a member
            --  of Targ_Typ. If the original Target_Type is an access, include
            --  a test for null value. The check is inserted at N.

            --------------------
            -- Make_Tag_Check --
            --------------------

            procedure Make_Tag_Check (Targ_Typ : Entity_Id) is
               Cond : Node_Id;

            begin
               --  Generate:
               --    [Constraint_Error
               --       when Operand /= null
               --         and then Operand.all not in Targ_Typ]

               if Is_Access_Type (Target_Type) then
                  Cond :=
                    Make_And_Then (Loc,
                      Left_Opnd =>
                        Make_Op_Ne (Loc,
                          Left_Opnd  => Duplicate_Subexpr_No_Checks (Operand),
                          Right_Opnd => Make_Null (Loc)),

                      Right_Opnd =>
                        Make_Not_In (Loc,
                          Left_Opnd  =>
                            Make_Explicit_Dereference (Loc,
                              Prefix => Duplicate_Subexpr_No_Checks (Operand)),
                          Right_Opnd => New_Occurrence_Of (Targ_Typ, Loc)));

               --  Generate:
               --    [Constraint_Error when Operand not in Targ_Typ]

               else
                  Cond :=
                    Make_Not_In (Loc,
                      Left_Opnd  => Duplicate_Subexpr_No_Checks (Operand),
                      Right_Opnd => New_Occurrence_Of (Targ_Typ, Loc));
               end if;

               Insert_Action (N,
                 Make_Raise_Constraint_Error (Loc,
                   Condition => Cond,
                   Reason    => CE_Tag_Check_Failed),
                 Suppress => All_Checks);
            end Make_Tag_Check;

         --  Start of processing for Tagged_Conversion

         begin
            --  Handle entities from the limited view

            if Is_Access_Type (Operand_Type) then
               Actual_Op_Typ :=
                 Available_View (Designated_Type (Operand_Type));
            else
               Actual_Op_Typ := Operand_Type;
            end if;

            if Is_Access_Type (Target_Type) then
               Actual_Targ_Typ :=
                 Available_View (Designated_Type (Target_Type));
            else
               Actual_Targ_Typ := Target_Type;
            end if;

            Root_Op_Typ := Root_Type (Actual_Op_Typ);

            --  Ada 2005 (AI-251): Handle interface type conversion

            if Is_Interface (Actual_Op_Typ)
                 or else
               Is_Interface (Actual_Targ_Typ)
            then
               Expand_Interface_Conversion (N);
               goto Done;
            end if;

            if not Tag_Checks_Suppressed (Actual_Targ_Typ) then

               --  Create a runtime tag check for a downward class-wide type
               --  conversion.

               if Is_Class_Wide_Type (Actual_Op_Typ)
                 and then Actual_Op_Typ /= Actual_Targ_Typ
                 and then Root_Op_Typ /= Actual_Targ_Typ
                 and then Is_Ancestor (Root_Op_Typ, Actual_Targ_Typ,
                                       Use_Full_View => True)
               then
                  Make_Tag_Check (Class_Wide_Type (Actual_Targ_Typ));
                  Make_Conversion := True;
               end if;

               --  AI05-0073: If the result subtype of the function is defined
               --  by an access_definition designating a specific tagged type
               --  T, a check is made that the result value is null or the tag
               --  of the object designated by the result value identifies T.
               --  Constraint_Error is raised if this check fails.

               if Nkind (Parent (N)) = N_Simple_Return_Statement then
                  declare
                     Func     : Entity_Id;
                     Func_Typ : Entity_Id;

                  begin
                     --  Climb scope stack looking for the enclosing function

                     Func := Current_Scope;
                     while Present (Func)
                       and then Ekind (Func) /= E_Function
                     loop
                        Func := Scope (Func);
                     end loop;

                     --  The function's return subtype must be defined using
                     --  an access definition.

                     if Nkind (Result_Definition (Parent (Func))) =
                          N_Access_Definition
                     then
                        Func_Typ := Directly_Designated_Type (Etype (Func));

                        --  The return subtype denotes a specific tagged type,
                        --  in other words, a non class-wide type.

                        if Is_Tagged_Type (Func_Typ)
                          and then not Is_Class_Wide_Type (Func_Typ)
                        then
                           Make_Tag_Check (Actual_Targ_Typ);
                           Make_Conversion := True;
                        end if;
                     end if;
                  end;
               end if;

               --  We have generated a tag check for either a class-wide type
               --  conversion or for AI05-0073.

               if Make_Conversion then
                  declare
                     Conv : Node_Id;
                  begin
                     Conv :=
                       Make_Unchecked_Type_Conversion (Loc,
                         Subtype_Mark => New_Occurrence_Of (Target_Type, Loc),
                         Expression   => Relocate_Node (Expression (N)));
                     Rewrite (N, Conv);
                     Analyze_And_Resolve (N, Target_Type);
                  end;
               end if;
            end if;
         end Tagged_Conversion;

      --  Case of other access type conversions

      elsif Is_Access_Type (Target_Type) then
         Apply_Constraint_Check (Operand, Target_Type);

      --  Case of conversions from a fixed-point type

      --  These conversions require special expansion and processing, found in
      --  the Exp_Fixd package. We ignore cases where Conversion_OK is set,
      --  since from a semantic point of view, these are simple integer
      --  conversions, which do not need further processing.

      elsif Is_Fixed_Point_Type (Operand_Type)
        and then not Conversion_OK (N)
      then
         --  We should never see universal fixed at this case, since the
         --  expansion of the constituent divide or multiply should have
         --  eliminated the explicit mention of universal fixed.

         pragma Assert (Operand_Type /= Universal_Fixed);

         --  Check for special case of the conversion to universal real that
         --  occurs as a result of the use of a round attribute. In this case,
         --  the real type for the conversion is taken from the target type of
         --  the Round attribute and the result must be marked as rounded.

         if Target_Type = Universal_Real
           and then Nkind (Parent (N)) = N_Attribute_Reference
           and then Attribute_Name (Parent (N)) = Name_Round
         then
            Set_Rounded_Result (N);
            Set_Etype (N, Etype (Parent (N)));
            Target_Type := Etype (N);
         end if;

         if Is_Fixed_Point_Type (Target_Type) then
            Expand_Convert_Fixed_To_Fixed (N);
            Real_Range_Check;

         elsif Is_Integer_Type (Target_Type) then
            Expand_Convert_Fixed_To_Integer (N);
            Discrete_Range_Check;

         else
            pragma Assert (Is_Floating_Point_Type (Target_Type));
            Expand_Convert_Fixed_To_Float (N);
            Real_Range_Check;
         end if;

      --  Case of conversions to a fixed-point type

      --  These conversions require special expansion and processing, found in
      --  the Exp_Fixd package. Again, ignore cases where Conversion_OK is set,
      --  since from a semantic point of view, these are simple integer
      --  conversions, which do not need further processing.

      elsif Is_Fixed_Point_Type (Target_Type)
        and then not Conversion_OK (N)
      then
         if Is_Integer_Type (Operand_Type) then
            Expand_Convert_Integer_To_Fixed (N);
            Real_Range_Check;
         else
            pragma Assert (Is_Floating_Point_Type (Operand_Type));
            Expand_Convert_Float_To_Fixed (N);
            Real_Range_Check;
         end if;

      --  Case of array conversions

      --  Expansion of array conversions, add required length/range checks but
      --  only do this if there is no change of representation. For handling of
      --  this case, see Handle_Changed_Representation.

      elsif Is_Array_Type (Target_Type) then
         if Is_Constrained (Target_Type) then
            Apply_Length_Check (Operand, Target_Type);
         else
            Apply_Range_Check (Operand, Target_Type);
         end if;

         Handle_Changed_Representation;

      --  Case of conversions of discriminated types

      --  Add required discriminant checks if target is constrained. Again this
      --  change is skipped if we have a change of representation.

      elsif Has_Discriminants (Target_Type)
        and then Is_Constrained (Target_Type)
      then
         Apply_Discriminant_Check (Operand, Target_Type);
         Handle_Changed_Representation;

      --  Case of all other record conversions. The only processing required
      --  is to check for a change of representation requiring the special
      --  assignment processing.

      elsif Is_Record_Type (Target_Type) then

         --  Ada 2005 (AI-216): Program_Error is raised when converting from
         --  a derived Unchecked_Union type to an unconstrained type that is
         --  not Unchecked_Union if the operand lacks inferable discriminants.

         if Is_Derived_Type (Operand_Type)
           and then Is_Unchecked_Union (Base_Type (Operand_Type))
           and then not Is_Constrained (Target_Type)
           and then not Is_Unchecked_Union (Base_Type (Target_Type))
           and then not Has_Inferable_Discriminants (Operand)
         then
            --  To prevent Gigi from generating illegal code, we generate a
            --  Program_Error node, but we give it the target type of the
            --  conversion (is this requirement documented somewhere ???)

            declare
               PE : constant Node_Id := Make_Raise_Program_Error (Loc,
                      Reason => PE_Unchecked_Union_Restriction);

            begin
               Set_Etype (PE, Target_Type);
               Rewrite (N, PE);

            end;
         else
            Handle_Changed_Representation;
         end if;

      --  Case of conversions of enumeration types

      elsif Is_Enumeration_Type (Target_Type) then

         --  Special processing is required if there is a change of
         --  representation (from enumeration representation clauses).

         if not Same_Representation (Target_Type, Operand_Type) then

            --  Convert: x(y) to x'val (ytyp'val (y))

            Rewrite (N,
              Make_Attribute_Reference (Loc,
                Prefix         => New_Occurrence_Of (Target_Type, Loc),
                Attribute_Name => Name_Val,
                Expressions    => New_List (
                  Make_Attribute_Reference (Loc,
                    Prefix         => New_Occurrence_Of (Operand_Type, Loc),
                    Attribute_Name => Name_Pos,
                    Expressions    => New_List (Operand)))));

            Analyze_And_Resolve (N, Target_Type);
         end if;
      end if;

      --  At this stage, either the conversion node has been transformed into
      --  some other equivalent expression, or left as a conversion that can be
      --  handled by Gigi, in the following cases:

      --    Conversions with no change of representation or type

      --    Numeric conversions involving integer, floating- and fixed-point
      --    values. Fixed-point values are allowed only if Conversion_OK is
      --    set, i.e. if the fixed-point values are to be treated as integers.

      --  No other conversions should be passed to Gigi

      --  Check: are these rules stated in sinfo??? if so, why restate here???

      --  The only remaining step is to generate a range check if we still have
      --  a type conversion at this stage and Do_Range_Check is set. Note that
      --  we need to deal with at most 8 out of the 9 possible cases of numeric
      --  conversions here, because the float-to-integer case is entirely dealt
      --  with by Apply_Float_Conversion_Check.

      if Nkind (N) = N_Type_Conversion
        and then Do_Range_Check (Expression (N))
      then
         --  Float-to-float conversions

         if Is_Floating_Point_Type (Target_Type)
           and then Is_Floating_Point_Type (Etype (Expression (N)))
         then
            --  Reset overflow flag, since the range check will include
            --  dealing with possible overflow, and generate the check.

            Set_Do_Overflow_Check (N, False);

            Generate_Range_Check
              (Expression (N), Target_Type, CE_Range_Check_Failed);

         --  Discrete-to-discrete conversions or fixed-point-to-discrete
         --  conversions when Conversion_OK is set.

         elsif Is_Discrete_Type (Target_Type)
           and then (Is_Discrete_Type (Etype (Expression (N)))
                      or else (Is_Fixed_Point_Type (Etype (Expression (N)))
                                and then Conversion_OK (N)))
         then
            --  If Address is either a source type or target type,
            --  suppress range check to avoid typing anomalies when
            --  it is a visible integer type.

            if Is_Descendant_Of_Address (Etype (Expression (N)))
              or else Is_Descendant_Of_Address (Target_Type)
            then
               Set_Do_Range_Check (Expression (N), False);
            else
               Discrete_Range_Check;
            end if;

         --  Conversions to floating- or fixed-point when Conversion_OK is set

         elsif Is_Floating_Point_Type (Target_Type)
           or else (Is_Fixed_Point_Type (Target_Type)
                     and then Conversion_OK (N))
         then
            Real_Range_Check;
         end if;
      end if;

      --  Here at end of processing

   <<Done>>
      --  Apply predicate check if required. Note that we can't just call
      --  Apply_Predicate_Check here, because the type looks right after
      --  the conversion and it would omit the check. The Comes_From_Source
      --  guard is necessary to prevent infinite recursions when we generate
      --  internal conversions for the purpose of checking predicates.

      if Present (Predicate_Function (Target_Type))
        and then not Predicates_Ignored (Target_Type)
        and then Target_Type /= Operand_Type
        and then Comes_From_Source (N)
      then
         declare
            New_Expr : constant Node_Id := Duplicate_Subexpr (N);

         begin
            --  Avoid infinite recursion on the subsequent expansion of
            --  of the copy of the original type conversion. When needed,
            --  a range check has already been applied to the expression.

            Set_Comes_From_Source (New_Expr, False);
            Insert_Action (N,
               Make_Predicate_Check (Target_Type, New_Expr),
               Suppress => Range_Check);
         end;
      end if;
   end Expand_N_Type_Conversion;

   -----------------------------------
   -- Expand_N_Unchecked_Expression --
   -----------------------------------

   --  Remove the unchecked expression node from the tree. Its job was simply
   --  to make sure that its constituent expression was handled with checks
   --  off, and now that is done, we can remove it from the tree, and indeed
   --  must, since Gigi does not expect to see these nodes.

   procedure Expand_N_Unchecked_Expression (N : Node_Id) is
      Exp : constant Node_Id := Expression (N);
   begin
      Set_Assignment_OK (Exp, Assignment_OK (N) or else Assignment_OK (Exp));
      Rewrite (N, Exp);
   end Expand_N_Unchecked_Expression;

   ----------------------------------------
   -- Expand_N_Unchecked_Type_Conversion --
   ----------------------------------------

   --  If this cannot be handled by Gigi and we haven't already made a
   --  temporary for it, do it now.

   procedure Expand_N_Unchecked_Type_Conversion (N : Node_Id) is
      Target_Type  : constant Entity_Id := Etype (N);
      Operand      : constant Node_Id   := Expression (N);
      Operand_Type : constant Entity_Id := Etype (Operand);

   begin
      --  Nothing at all to do if conversion is to the identical type so remove
      --  the conversion completely, it is useless, except that it may carry
      --  an Assignment_OK indication which must be propagated to the operand.

      if Operand_Type = Target_Type then

         --  Code duplicates Expand_N_Unchecked_Expression above, factor???

         if Assignment_OK (N) then
            Set_Assignment_OK (Operand);
         end if;

         Rewrite (N, Relocate_Node (Operand));
         return;
      end if;

      --  If we have a conversion of a compile time known value to a target
      --  type and the value is in range of the target type, then we can simply
      --  replace the construct by an integer literal of the correct type. We
      --  only apply this to integer types being converted. Possibly it may
      --  apply in other cases, but it is too much trouble to worry about.

      --  Note that we do not do this transformation if the Kill_Range_Check
      --  flag is set, since then the value may be outside the expected range.
      --  This happens in the Normalize_Scalars case.

      --  We also skip this if either the target or operand type is biased
      --  because in this case, the unchecked conversion is supposed to
      --  preserve the bit pattern, not the integer value.

      if Is_Integer_Type (Target_Type)
        and then not Has_Biased_Representation (Target_Type)
        and then Is_Integer_Type (Operand_Type)
        and then not Has_Biased_Representation (Operand_Type)
        and then Compile_Time_Known_Value (Operand)
        and then not Kill_Range_Check (N)
      then
         declare
            Val : constant Uint := Expr_Value (Operand);

         begin
            if Compile_Time_Known_Value (Type_Low_Bound (Target_Type))
                 and then
               Compile_Time_Known_Value (Type_High_Bound (Target_Type))
                 and then
               Val >= Expr_Value (Type_Low_Bound (Target_Type))
                 and then
               Val <= Expr_Value (Type_High_Bound (Target_Type))
            then
               Rewrite (N, Make_Integer_Literal (Sloc (N), Val));

               --  If Address is the target type, just set the type to avoid a
               --  spurious type error on the literal when Address is a visible
               --  integer type.

               if Is_Descendant_Of_Address (Target_Type) then
                  Set_Etype (N, Target_Type);
               else
                  Analyze_And_Resolve (N, Target_Type);
               end if;

               return;
            end if;
         end;
      end if;

      --  Generate an extra temporary for cases unsupported by the C backend

      if Modify_Tree_For_C then
         declare
            Source     : constant Node_Id := Unqual_Conv (Expression (N));
            Source_Typ : Entity_Id        := Get_Full_View (Etype (Source));

         begin
            if Is_Packed_Array (Source_Typ) then
               Source_Typ := Packed_Array_Impl_Type (Source_Typ);
            end if;

            if Nkind (Source) = N_Function_Call
              and then (Is_Composite_Type (Etype (Source))
                          or else Is_Composite_Type (Target_Type))
            then
               Force_Evaluation (Source);
            end if;
         end;
      end if;

      --  Nothing to do if conversion is safe

      if Safe_Unchecked_Type_Conversion (N) then
         return;
      end if;

      --  Otherwise force evaluation unless Assignment_OK flag is set (this
      --  flag indicates ??? More comments needed here)

      if Assignment_OK (N) then
         null;
      else
         Force_Evaluation (N);
      end if;
   end Expand_N_Unchecked_Type_Conversion;

   ----------------------------
   -- Expand_Record_Equality --
   ----------------------------

   --  For non-variant records, Equality is expanded when needed into:

   --      and then Lhs.Discr1 = Rhs.Discr1
   --      and then ...
   --      and then Lhs.Discrn = Rhs.Discrn
   --      and then Lhs.Cmp1 = Rhs.Cmp1
   --      and then ...
   --      and then Lhs.Cmpn = Rhs.Cmpn

   --  The expression is folded by the back end for adjacent fields. This
   --  function is called for tagged record in only one occasion: for imple-
   --  menting predefined primitive equality (see Predefined_Primitives_Bodies)
   --  otherwise the primitive "=" is used directly.

   function Expand_Record_Equality
     (Nod    : Node_Id;
      Typ    : Entity_Id;
      Lhs    : Node_Id;
      Rhs    : Node_Id;
      Bodies : List_Id) return Node_Id
   is
      Loc : constant Source_Ptr := Sloc (Nod);

      Result : Node_Id;
      C      : Entity_Id;

      First_Time : Boolean := True;

      function Element_To_Compare (C : Entity_Id) return Entity_Id;
      --  Return the next discriminant or component to compare, starting with
      --  C, skipping inherited components.

      ------------------------
      -- Element_To_Compare --
      ------------------------

      function Element_To_Compare (C : Entity_Id) return Entity_Id is
         Comp : Entity_Id;

      begin
         Comp := C;
         loop
            --  Exit loop when the next element to be compared is found, or
            --  there is no more such element.

            exit when No (Comp);

            exit when Ekind_In (Comp, E_Discriminant, E_Component)
              and then not (

              --  Skip inherited components

              --  Note: for a tagged type, we always generate the "=" primitive
              --  for the base type (not on the first subtype), so the test for
              --  Comp /= Original_Record_Component (Comp) is True for
              --  inherited components only.

              (Is_Tagged_Type (Typ)
                and then Comp /= Original_Record_Component (Comp))

              --  Skip _Tag

              or else Chars (Comp) = Name_uTag

              --  Skip interface elements (secondary tags???)

              or else Is_Interface (Etype (Comp)));

            Next_Entity (Comp);
         end loop;

         return Comp;
      end Element_To_Compare;

   --  Start of processing for Expand_Record_Equality

   begin
      --  Generates the following code: (assuming that Typ has one Discr and
      --  component C2 is also a record)

      --  Lhs.Discr1 = Rhs.Discr1
      --    and then Lhs.C1 = Rhs.C1
      --    and then Lhs.C2.C1=Rhs.C2.C1 and then ... Lhs.C2.Cn=Rhs.C2.Cn
      --    and then ...
      --    and then Lhs.Cmpn = Rhs.Cmpn

      Result := New_Occurrence_Of (Standard_True, Loc);
      C := Element_To_Compare (First_Entity (Typ));
      while Present (C) loop
         declare
            New_Lhs : Node_Id;
            New_Rhs : Node_Id;
            Check   : Node_Id;

         begin
            if First_Time then
               New_Lhs := Lhs;
               New_Rhs := Rhs;
            else
               New_Lhs := New_Copy_Tree (Lhs);
               New_Rhs := New_Copy_Tree (Rhs);
            end if;

            Check :=
              Expand_Composite_Equality (Nod, Etype (C),
               Lhs =>
                 Make_Selected_Component (Loc,
                   Prefix        => New_Lhs,
                   Selector_Name => New_Occurrence_Of (C, Loc)),
               Rhs =>
                 Make_Selected_Component (Loc,
                   Prefix        => New_Rhs,
                   Selector_Name => New_Occurrence_Of (C, Loc)),
               Bodies => Bodies);

            --  If some (sub)component is an unchecked_union, the whole
            --  operation will raise program error.

            if Nkind (Check) = N_Raise_Program_Error then
               Result := Check;
               Set_Etype (Result, Standard_Boolean);
               exit;
            else
               if First_Time then
                  Result := Check;

               --  Generate logical "and" for CodePeer to simplify the
               --  generated code and analysis.

               elsif CodePeer_Mode then
                  Result :=
                    Make_Op_And (Loc,
                      Left_Opnd  => Result,
                      Right_Opnd => Check);

               else
                  Result :=
                    Make_And_Then (Loc,
                      Left_Opnd  => Result,
                      Right_Opnd => Check);
               end if;
            end if;
         end;

         First_Time := False;
         C := Element_To_Compare (Next_Entity (C));
      end loop;

      return Result;
   end Expand_Record_Equality;

   ---------------------------
   -- Expand_Set_Membership --
   ---------------------------

   procedure Expand_Set_Membership (N : Node_Id) is
      Lop : constant Node_Id := Left_Opnd (N);
      Alt : Node_Id;
      Res : Node_Id;

      function Make_Cond (Alt : Node_Id) return Node_Id;
      --  If the alternative is a subtype mark, create a simple membership
      --  test. Otherwise create an equality test for it.

      ---------------
      -- Make_Cond --
      ---------------

      function Make_Cond (Alt : Node_Id) return Node_Id is
         Cond : Node_Id;
         L    : constant Node_Id := New_Copy_Tree (Lop);
         R    : constant Node_Id := Relocate_Node (Alt);

      begin
         if (Is_Entity_Name (Alt) and then Is_Type (Entity (Alt)))
           or else Nkind (Alt) = N_Range
         then
            Cond :=
              Make_In (Sloc (Alt),
                Left_Opnd  => L,
                Right_Opnd => R);
         else
            Cond :=
              Make_Op_Eq (Sloc (Alt),
                Left_Opnd  => L,
                Right_Opnd => R);
         end if;

         return Cond;
      end Make_Cond;

   --  Start of processing for Expand_Set_Membership

   begin
      Remove_Side_Effects (Lop);

      Alt := Last (Alternatives (N));
      Res := Make_Cond (Alt);

      Prev (Alt);
      while Present (Alt) loop
         Res :=
           Make_Or_Else (Sloc (Alt),
             Left_Opnd  => Make_Cond (Alt),
             Right_Opnd => Res);
         Prev (Alt);
      end loop;

      Rewrite (N, Res);
      Analyze_And_Resolve (N, Standard_Boolean);
   end Expand_Set_Membership;

   -----------------------------------
   -- Expand_Short_Circuit_Operator --
   -----------------------------------

   --  Deal with special expansion if actions are present for the right operand
   --  and deal with optimizing case of arguments being True or False. We also
   --  deal with the special case of non-standard boolean values.

   procedure Expand_Short_Circuit_Operator (N : Node_Id) is
      Loc     : constant Source_Ptr := Sloc (N);
      Typ     : constant Entity_Id  := Etype (N);
      Left    : constant Node_Id    := Left_Opnd (N);
      Right   : constant Node_Id    := Right_Opnd (N);
      LocR    : constant Source_Ptr := Sloc (Right);
      Actlist : List_Id;

      Shortcut_Value : constant Boolean := Nkind (N) = N_Or_Else;
      Shortcut_Ent   : constant Entity_Id := Boolean_Literals (Shortcut_Value);
      --  If Left = Shortcut_Value then Right need not be evaluated

      function Make_Test_Expr (Opnd : Node_Id) return Node_Id;
      --  For Opnd a boolean expression, return a Boolean expression equivalent
      --  to Opnd /= Shortcut_Value.

      function Useful (Actions : List_Id) return Boolean;
      --  Return True if Actions is not empty and contains useful nodes to
      --  process.

      --------------------
      -- Make_Test_Expr --
      --------------------

      function Make_Test_Expr (Opnd : Node_Id) return Node_Id is
      begin
         if Shortcut_Value then
            return Make_Op_Not (Sloc (Opnd), Opnd);
         else
            return Opnd;
         end if;
      end Make_Test_Expr;

      ------------
      -- Useful --
      ------------

      function Useful (Actions : List_Id) return Boolean is
         L : Node_Id;
      begin
         if Present (Actions) then
            L := First (Actions);

            --  For now "useful" means not N_Variable_Reference_Marker.
            --  Consider stripping other nodes in the future.

            while Present (L) loop
               if Nkind (L) /= N_Variable_Reference_Marker then
                  return True;
               end if;

               Next (L);
            end loop;
         end if;

         return False;
      end Useful;

      --  Local variables

      Op_Var : Entity_Id;
      --  Entity for a temporary variable holding the value of the operator,
      --  used for expansion in the case where actions are present.

   --  Start of processing for Expand_Short_Circuit_Operator

   begin
      --  Deal with non-standard booleans

      if Is_Boolean_Type (Typ) then
         Adjust_Condition (Left);
         Adjust_Condition (Right);
         Set_Etype (N, Standard_Boolean);
      end if;

      --  Check for cases where left argument is known to be True or False

      if Compile_Time_Known_Value (Left) then

         --  Mark SCO for left condition as compile time known

         if Generate_SCO and then Comes_From_Source (Left) then
            Set_SCO_Condition (Left, Expr_Value_E (Left) = Standard_True);
         end if;

         --  Rewrite True AND THEN Right / False OR ELSE Right to Right.
         --  Any actions associated with Right will be executed unconditionally
         --  and can thus be inserted into the tree unconditionally.

         if Expr_Value_E (Left) /= Shortcut_Ent then
            if Present (Actions (N)) then
               Insert_Actions (N, Actions (N));
            end if;

            Rewrite (N, Right);

         --  Rewrite False AND THEN Right / True OR ELSE Right to Left.
         --  In this case we can forget the actions associated with Right,
         --  since they will never be executed.

         else
            Kill_Dead_Code (Right);
            Kill_Dead_Code (Actions (N));
            Rewrite (N, New_Occurrence_Of (Shortcut_Ent, Loc));
         end if;

         Adjust_Result_Type (N, Typ);
         return;
      end if;

      --  If Actions are present for the right operand, we have to do some
      --  special processing. We can't just let these actions filter back into
      --  code preceding the short circuit (which is what would have happened
      --  if we had not trapped them in the short-circuit form), since they
      --  must only be executed if the right operand of the short circuit is
      --  executed and not otherwise.

      if Useful (Actions (N)) then
         Actlist := Actions (N);

         --  The old approach is to expand:

         --     left AND THEN right

         --  into

         --     C : Boolean := False;
         --     IF left THEN
         --        Actions;
         --        IF right THEN
         --           C := True;
         --        END IF;
         --     END IF;

         --  and finally rewrite the operator into a reference to C. Similarly
         --  for left OR ELSE right, with negated values. Note that this
         --  rewrite causes some difficulties for coverage analysis because
         --  of the introduction of the new variable C, which obscures the
         --  structure of the test.

         --  We use this "old approach" if Minimize_Expression_With_Actions
         --  is True.

         if Minimize_Expression_With_Actions then
            Op_Var := Make_Temporary (Loc, 'C', Related_Node => N);

            Insert_Action (N,
              Make_Object_Declaration (Loc,
                Defining_Identifier => Op_Var,
                Object_Definition   =>
                  New_Occurrence_Of (Standard_Boolean, Loc),
                Expression          =>
                  New_Occurrence_Of (Shortcut_Ent, Loc)));

            Append_To (Actlist,
              Make_Implicit_If_Statement (Right,
                Condition       => Make_Test_Expr (Right),
                Then_Statements => New_List (
                  Make_Assignment_Statement (LocR,
                    Name       => New_Occurrence_Of (Op_Var, LocR),
                    Expression =>
                      New_Occurrence_Of
                        (Boolean_Literals (not Shortcut_Value), LocR)))));

            Insert_Action (N,
              Make_Implicit_If_Statement (Left,
                Condition       => Make_Test_Expr (Left),
                Then_Statements => Actlist));

            Rewrite (N, New_Occurrence_Of (Op_Var, Loc));
            Analyze_And_Resolve (N, Standard_Boolean);

         --  The new approach (the default) is to use an
         --  Expression_With_Actions node for the right operand of the
         --  short-circuit form. Note that this solves the traceability
         --  problems for coverage analysis.

         else
            Rewrite (Right,
              Make_Expression_With_Actions (LocR,
                Expression => Relocate_Node (Right),
                Actions    => Actlist));

            Set_Actions (N, No_List);
            Analyze_And_Resolve (Right, Standard_Boolean);
         end if;

         Adjust_Result_Type (N, Typ);
         return;
      end if;

      --  No actions present, check for cases of right argument True/False

      if Compile_Time_Known_Value (Right) then

         --  Mark SCO for left condition as compile time known

         if Generate_SCO and then Comes_From_Source (Right) then
            Set_SCO_Condition (Right, Expr_Value_E (Right) = Standard_True);
         end if;

         --  Change (Left and then True), (Left or else False) to Left. Note
         --  that we know there are no actions associated with the right
         --  operand, since we just checked for this case above.

         if Expr_Value_E (Right) /= Shortcut_Ent then
            Rewrite (N, Left);

         --  Change (Left and then False), (Left or else True) to Right,
         --  making sure to preserve any side effects associated with the Left
         --  operand.

         else
            Remove_Side_Effects (Left);
            Rewrite (N, New_Occurrence_Of (Shortcut_Ent, Loc));
         end if;
      end if;

      Adjust_Result_Type (N, Typ);
   end Expand_Short_Circuit_Operator;

   ------------------------------------
   -- Fixup_Universal_Fixed_Operation --
   -------------------------------------

   procedure Fixup_Universal_Fixed_Operation (N : Node_Id) is
      Conv : constant Node_Id := Parent (N);

   begin
      --  We must have a type conversion immediately above us

      pragma Assert (Nkind (Conv) = N_Type_Conversion);

      --  Normally the type conversion gives our target type. The exception
      --  occurs in the case of the Round attribute, where the conversion
      --  will be to universal real, and our real type comes from the Round
      --  attribute (as well as an indication that we must round the result)

      if Nkind (Parent (Conv)) = N_Attribute_Reference
        and then Attribute_Name (Parent (Conv)) = Name_Round
      then
         Set_Etype (N, Base_Type (Etype (Parent (Conv))));
         Set_Rounded_Result (N);

      --  Normal case where type comes from conversion above us

      else
         Set_Etype (N, Base_Type (Etype (Conv)));
      end if;
   end Fixup_Universal_Fixed_Operation;

   ---------------------------------
   -- Has_Inferable_Discriminants --
   ---------------------------------

   function Has_Inferable_Discriminants (N : Node_Id) return Boolean is

      function Prefix_Is_Formal_Parameter (N : Node_Id) return Boolean;
      --  Determines whether the left-most prefix of a selected component is a
      --  formal parameter in a subprogram. Assumes N is a selected component.

      --------------------------------
      -- Prefix_Is_Formal_Parameter --
      --------------------------------

      function Prefix_Is_Formal_Parameter (N : Node_Id) return Boolean is
         Sel_Comp : Node_Id;

      begin
         --  Move to the left-most prefix by climbing up the tree

         Sel_Comp := N;
         while Present (Parent (Sel_Comp))
           and then Nkind (Parent (Sel_Comp)) = N_Selected_Component
         loop
            Sel_Comp := Parent (Sel_Comp);
         end loop;

         return Is_Formal (Entity (Prefix (Sel_Comp)));
      end Prefix_Is_Formal_Parameter;

   --  Start of processing for Has_Inferable_Discriminants

   begin
      --  For selected components, the subtype of the selector must be a
      --  constrained Unchecked_Union. If the component is subject to a
      --  per-object constraint, then the enclosing object must have inferable
      --  discriminants.

      if Nkind (N) = N_Selected_Component then
         if Has_Per_Object_Constraint (Entity (Selector_Name (N))) then

            --  A small hack. If we have a per-object constrained selected
            --  component of a formal parameter, return True since we do not
            --  know the actual parameter association yet.

            if Prefix_Is_Formal_Parameter (N) then
               return True;

            --  Otherwise, check the enclosing object and the selector

            else
               return Has_Inferable_Discriminants (Prefix (N))
                 and then Has_Inferable_Discriminants (Selector_Name (N));
            end if;

         --  The call to Has_Inferable_Discriminants will determine whether
         --  the selector has a constrained Unchecked_Union nominal type.

         else
            return Has_Inferable_Discriminants (Selector_Name (N));
         end if;

      --  A qualified expression has inferable discriminants if its subtype
      --  mark is a constrained Unchecked_Union subtype.

      elsif Nkind (N) = N_Qualified_Expression then
         return Is_Unchecked_Union (Etype (Subtype_Mark (N)))
           and then Is_Constrained (Etype (Subtype_Mark (N)));

      --  For all other names, it is sufficient to have a constrained
      --  Unchecked_Union nominal subtype.

      else
         return Is_Unchecked_Union (Base_Type (Etype (N)))
           and then Is_Constrained (Etype (N));
      end if;
   end Has_Inferable_Discriminants;

   -------------------------------
   -- Insert_Dereference_Action --
   -------------------------------

   procedure Insert_Dereference_Action (N : Node_Id) is
      function Is_Checked_Storage_Pool (P : Entity_Id) return Boolean;
      --  Return true if type of P is derived from Checked_Pool;

      -----------------------------
      -- Is_Checked_Storage_Pool --
      -----------------------------

      function Is_Checked_Storage_Pool (P : Entity_Id) return Boolean is
         T : Entity_Id;

      begin
         if No (P) then
            return False;
         end if;

         T := Etype (P);
         while T /= Etype (T) loop
            if Is_RTE (T, RE_Checked_Pool) then
               return True;
            else
               T := Etype (T);
            end if;
         end loop;

         return False;
      end Is_Checked_Storage_Pool;

      --  Local variables

      Context   : constant Node_Id    := Parent (N);
      Ptr_Typ   : constant Entity_Id  := Etype (N);
      Desig_Typ : constant Entity_Id  :=
                    Available_View (Designated_Type (Ptr_Typ));
      Loc       : constant Source_Ptr := Sloc (N);
      Pool      : constant Entity_Id  := Associated_Storage_Pool (Ptr_Typ);

      Addr      : Entity_Id;
      Alig      : Entity_Id;
      Deref     : Node_Id;
      Size      : Entity_Id;
      Size_Bits : Node_Id;
      Stmt      : Node_Id;

   --  Start of processing for Insert_Dereference_Action

   begin
      pragma Assert (Nkind (Context) = N_Explicit_Dereference);

      --  Do not re-expand a dereference which has already been processed by
      --  this routine.

      if Has_Dereference_Action (Context) then
         return;

      --  Do not perform this type of expansion for internally-generated
      --  dereferences.

      elsif not Comes_From_Source (Original_Node (Context)) then
         return;

      --  A dereference action is only applicable to objects which have been
      --  allocated on a checked pool.

      elsif not Is_Checked_Storage_Pool (Pool) then
         return;
      end if;

      --  Extract the address of the dereferenced object. Generate:

      --    Addr : System.Address := <N>'Pool_Address;

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

      Insert_Action (N,
        Make_Object_Declaration (Loc,
          Defining_Identifier => Addr,
          Object_Definition   =>
            New_Occurrence_Of (RTE (RE_Address), Loc),
          Expression          =>
            Make_Attribute_Reference (Loc,
              Prefix         => Duplicate_Subexpr_Move_Checks (N),
              Attribute_Name => Name_Pool_Address)));

      --  Calculate the size of the dereferenced object. Generate:

      --    Size : Storage_Count := <N>.all'Size / Storage_Unit;

      Deref :=
        Make_Explicit_Dereference (Loc,
          Prefix => Duplicate_Subexpr_Move_Checks (N));
      Set_Has_Dereference_Action (Deref);

      Size_Bits :=
        Make_Attribute_Reference (Loc,
          Prefix         => Deref,
          Attribute_Name => Name_Size);

      --  Special case of an unconstrained array: need to add descriptor size

      if Is_Array_Type (Desig_Typ)
        and then not Is_Constrained (First_Subtype (Desig_Typ))
      then
         Size_Bits :=
           Make_Op_Add (Loc,
             Left_Opnd  =>
               Make_Attribute_Reference (Loc,
                 Prefix         =>
                   New_Occurrence_Of (First_Subtype (Desig_Typ), Loc),
                 Attribute_Name => Name_Descriptor_Size),
             Right_Opnd => Size_Bits);
      end if;

      Size := Make_Temporary (Loc, 'S');
      Insert_Action (N,
        Make_Object_Declaration (Loc,
          Defining_Identifier => Size,
          Object_Definition   =>
            New_Occurrence_Of (RTE (RE_Storage_Count), Loc),
          Expression          =>
            Make_Op_Divide (Loc,
              Left_Opnd  => Size_Bits,
              Right_Opnd => Make_Integer_Literal (Loc, System_Storage_Unit))));

      --  Calculate the alignment of the dereferenced object. Generate:
      --    Alig : constant Storage_Count := <N>.all'Alignment;

      Deref :=
        Make_Explicit_Dereference (Loc,
          Prefix => Duplicate_Subexpr_Move_Checks (N));
      Set_Has_Dereference_Action (Deref);

      Alig := Make_Temporary (Loc, 'A');
      Insert_Action (N,
        Make_Object_Declaration (Loc,
          Defining_Identifier => Alig,
          Object_Definition   =>
            New_Occurrence_Of (RTE (RE_Storage_Count), Loc),
          Expression          =>
            Make_Attribute_Reference (Loc,
              Prefix         => Deref,
              Attribute_Name => Name_Alignment)));

      --  A dereference of a controlled object requires special processing. The
      --  finalization machinery requests additional space from the underlying
      --  pool to allocate and hide two pointers. As a result, a checked pool
      --  may mark the wrong memory as valid. Since checked pools do not have
      --  knowledge of hidden pointers, we have to bring the two pointers back
      --  in view in order to restore the original state of the object.

      --  The address manipulation is not performed for access types that are
      --  subject to pragma No_Heap_Finalization because the two pointers do
      --  not exist in the first place.

      if No_Heap_Finalization (Ptr_Typ) then
         null;

      elsif Needs_Finalization (Desig_Typ) then

         --  Adjust the address and size of the dereferenced object. Generate:
         --    Adjust_Controlled_Dereference (Addr, Size, Alig);

         Stmt :=
           Make_Procedure_Call_Statement (Loc,
             Name                   =>
               New_Occurrence_Of (RTE (RE_Adjust_Controlled_Dereference), Loc),
             Parameter_Associations => New_List (
               New_Occurrence_Of (Addr, Loc),
               New_Occurrence_Of (Size, Loc),
               New_Occurrence_Of (Alig, Loc)));

         --  Class-wide types complicate things because we cannot determine
         --  statically whether the actual object is truly controlled. We must
         --  generate a runtime check to detect this property. Generate:
         --
         --    if Needs_Finalization (<N>.all'Tag) then
         --       <Stmt>;
         --    end if;

         if Is_Class_Wide_Type (Desig_Typ) then
            Deref :=
              Make_Explicit_Dereference (Loc,
                Prefix => Duplicate_Subexpr_Move_Checks (N));
            Set_Has_Dereference_Action (Deref);

            Stmt :=
              Make_Implicit_If_Statement (N,
                Condition       =>
                  Make_Function_Call (Loc,
                    Name                   =>
                      New_Occurrence_Of (RTE (RE_Needs_Finalization), Loc),
                    Parameter_Associations => New_List (
                      Make_Attribute_Reference (Loc,
                        Prefix         => Deref,
                        Attribute_Name => Name_Tag))),
                Then_Statements => New_List (Stmt));
         end if;

         Insert_Action (N, Stmt);
      end if;

      --  Generate:
      --    Dereference (Pool, Addr, Size, Alig);

      Insert_Action (N,
        Make_Procedure_Call_Statement (Loc,
          Name                   =>
            New_Occurrence_Of
              (Find_Prim_Op (Etype (Pool), Name_Dereference), Loc),
          Parameter_Associations => New_List (
            New_Occurrence_Of (Pool, Loc),
            New_Occurrence_Of (Addr, Loc),
            New_Occurrence_Of (Size, Loc),
            New_Occurrence_Of (Alig, Loc))));

      --  Mark the explicit dereference as processed to avoid potential
      --  infinite expansion.

      Set_Has_Dereference_Action (Context);

   exception
      when RE_Not_Available =>
         return;
   end Insert_Dereference_Action;

   --------------------------------
   -- Integer_Promotion_Possible --
   --------------------------------

   function Integer_Promotion_Possible (N : Node_Id) return Boolean is
      Operand           : constant Node_Id   := Expression (N);
      Operand_Type      : constant Entity_Id := Etype (Operand);
      Root_Operand_Type : constant Entity_Id := Root_Type (Operand_Type);

   begin
      pragma Assert (Nkind (N) = N_Type_Conversion);

      return

           --  We only do the transformation for source constructs. We assume
           --  that the expander knows what it is doing when it generates code.

           Comes_From_Source (N)

           --  If the operand type is Short_Integer or Short_Short_Integer,
           --  then we will promote to Integer, which is available on all
           --  targets, and is sufficient to ensure no intermediate overflow.
           --  Furthermore it is likely to be as efficient or more efficient
           --  than using the smaller type for the computation so we do this
           --  unconditionally.

           and then
             (Root_Operand_Type = Base_Type (Standard_Short_Integer)
                or else
              Root_Operand_Type = Base_Type (Standard_Short_Short_Integer))

           --  Test for interesting operation, which includes addition,
           --  division, exponentiation, multiplication, subtraction, absolute
           --  value and unary negation. Unary "+" is omitted since it is a
           --  no-op and thus can't overflow.

           and then Nkind_In (Operand, N_Op_Abs,
                                       N_Op_Add,
                                       N_Op_Divide,
                                       N_Op_Expon,
                                       N_Op_Minus,
                                       N_Op_Multiply,
                                       N_Op_Subtract);
   end Integer_Promotion_Possible;

   ------------------------------
   -- Make_Array_Comparison_Op --
   ------------------------------

   --  This is a hand-coded expansion of the following generic function:

   --  generic
   --    type elem is  (<>);
   --    type index is (<>);
   --    type a is array (index range <>) of elem;

   --  function Gnnn (X : a; Y: a) return boolean is
   --    J : index := Y'first;

   --  begin
   --    if X'length = 0 then
   --       return false;

   --    elsif Y'length = 0 then
   --       return true;

   --    else
   --      for I in X'range loop
   --        if X (I) = Y (J) then
   --          if J = Y'last then
   --            exit;
   --          else
   --            J := index'succ (J);
   --          end if;

   --        else
   --           return X (I) > Y (J);
   --        end if;
   --      end loop;

   --      return X'length > Y'length;
   --    end if;
   --  end Gnnn;

   --  Note that since we are essentially doing this expansion by hand, we
   --  do not need to generate an actual or formal generic part, just the
   --  instantiated function itself.

   --  Perhaps we could have the actual generic available in the run-time,
   --  obtained by rtsfind, and actually expand a real instantiation ???

   function Make_Array_Comparison_Op
     (Typ : Entity_Id;
      Nod : Node_Id) return Node_Id
   is
      Loc : constant Source_Ptr := Sloc (Nod);

      X : constant Entity_Id := Make_Defining_Identifier (Loc, Name_uX);
      Y : constant Entity_Id := Make_Defining_Identifier (Loc, Name_uY);
      I : constant Entity_Id := Make_Defining_Identifier (Loc, Name_uI);
      J : constant Entity_Id := Make_Defining_Identifier (Loc, Name_uJ);

      Index : constant Entity_Id := Base_Type (Etype (First_Index (Typ)));

      Loop_Statement : Node_Id;
      Loop_Body      : Node_Id;
      If_Stat        : Node_Id;
      Inner_If       : Node_Id;
      Final_Expr     : Node_Id;
      Func_Body      : Node_Id;
      Func_Name      : Entity_Id;
      Formals        : List_Id;
      Length1        : Node_Id;
      Length2        : Node_Id;

   begin
      --  if J = Y'last then
      --     exit;
      --  else
      --     J := index'succ (J);
      --  end if;

      Inner_If :=
        Make_Implicit_If_Statement (Nod,
          Condition =>
            Make_Op_Eq (Loc,
              Left_Opnd => New_Occurrence_Of (J, Loc),
              Right_Opnd =>
                Make_Attribute_Reference (Loc,
                  Prefix => New_Occurrence_Of (Y, Loc),
                  Attribute_Name => Name_Last)),

          Then_Statements => New_List (
                Make_Exit_Statement (Loc)),

          Else_Statements =>
            New_List (
              Make_Assignment_Statement (Loc,
                Name => New_Occurrence_Of (J, Loc),
                Expression =>
                  Make_Attribute_Reference (Loc,
                    Prefix => New_Occurrence_Of (Index, Loc),
                    Attribute_Name => Name_Succ,
                    Expressions => New_List (New_Occurrence_Of (J, Loc))))));

      --  if X (I) = Y (J) then
      --     if ... end if;
      --  else
      --     return X (I) > Y (J);
      --  end if;

      Loop_Body :=
        Make_Implicit_If_Statement (Nod,
          Condition =>
            Make_Op_Eq (Loc,
              Left_Opnd =>
                Make_Indexed_Component (Loc,
                  Prefix      => New_Occurrence_Of (X, Loc),
                  Expressions => New_List (New_Occurrence_Of (I, Loc))),

              Right_Opnd =>
                Make_Indexed_Component (Loc,
                  Prefix      => New_Occurrence_Of (Y, Loc),
                  Expressions => New_List (New_Occurrence_Of (J, Loc)))),

          Then_Statements => New_List (Inner_If),

          Else_Statements => New_List (
            Make_Simple_Return_Statement (Loc,
              Expression =>
                Make_Op_Gt (Loc,
                  Left_Opnd =>
                    Make_Indexed_Component (Loc,
                      Prefix      => New_Occurrence_Of (X, Loc),
                      Expressions => New_List (New_Occurrence_Of (I, Loc))),

                  Right_Opnd =>
                    Make_Indexed_Component (Loc,
                      Prefix      => New_Occurrence_Of (Y, Loc),
                      Expressions => New_List (
                        New_Occurrence_Of (J, Loc)))))));

      --  for I in X'range loop
      --     if ... end if;
      --  end loop;

      Loop_Statement :=
        Make_Implicit_Loop_Statement (Nod,
          Identifier => Empty,

          Iteration_Scheme =>
            Make_Iteration_Scheme (Loc,
              Loop_Parameter_Specification =>
                Make_Loop_Parameter_Specification (Loc,
                  Defining_Identifier => I,
                  Discrete_Subtype_Definition =>
                    Make_Attribute_Reference (Loc,
                      Prefix => New_Occurrence_Of (X, Loc),
                      Attribute_Name => Name_Range))),

          Statements => New_List (Loop_Body));

      --    if X'length = 0 then
      --       return false;
      --    elsif Y'length = 0 then
      --       return true;
      --    else
      --      for ... loop ... end loop;
      --      return X'length > Y'length;
      --    end if;

      Length1 :=
        Make_Attribute_Reference (Loc,
          Prefix => New_Occurrence_Of (X, Loc),
          Attribute_Name => Name_Length);

      Length2 :=
        Make_Attribute_Reference (Loc,
          Prefix => New_Occurrence_Of (Y, Loc),
          Attribute_Name => Name_Length);

      Final_Expr :=
        Make_Op_Gt (Loc,
          Left_Opnd  => Length1,
          Right_Opnd => Length2);

      If_Stat :=
        Make_Implicit_If_Statement (Nod,
          Condition =>
            Make_Op_Eq (Loc,
              Left_Opnd =>
                Make_Attribute_Reference (Loc,
                  Prefix => New_Occurrence_Of (X, Loc),
                  Attribute_Name => Name_Length),
              Right_Opnd =>
                Make_Integer_Literal (Loc, 0)),

          Then_Statements =>
            New_List (
              Make_Simple_Return_Statement (Loc,
                Expression => New_Occurrence_Of (Standard_False, Loc))),

          Elsif_Parts => New_List (
            Make_Elsif_Part (Loc,
              Condition =>
                Make_Op_Eq (Loc,
                  Left_Opnd =>
                    Make_Attribute_Reference (Loc,
                      Prefix => New_Occurrence_Of (Y, Loc),
                      Attribute_Name => Name_Length),
                  Right_Opnd =>
                    Make_Integer_Literal (Loc, 0)),

              Then_Statements =>
                New_List (
                  Make_Simple_Return_Statement (Loc,
                     Expression => New_Occurrence_Of (Standard_True, Loc))))),

          Else_Statements => New_List (
            Loop_Statement,
            Make_Simple_Return_Statement (Loc,
              Expression => Final_Expr)));

      --  (X : a; Y: a)

      Formals := New_List (
        Make_Parameter_Specification (Loc,
          Defining_Identifier => X,
          Parameter_Type      => New_Occurrence_Of (Typ, Loc)),

        Make_Parameter_Specification (Loc,
          Defining_Identifier => Y,
          Parameter_Type      => New_Occurrence_Of (Typ, Loc)));

      --  function Gnnn (...) return boolean is
      --    J : index := Y'first;
      --  begin
      --    if ... end if;
      --  end Gnnn;

      Func_Name := Make_Temporary (Loc, 'G');

      Func_Body :=
        Make_Subprogram_Body (Loc,
          Specification =>
            Make_Function_Specification (Loc,
              Defining_Unit_Name       => Func_Name,
              Parameter_Specifications => Formals,
              Result_Definition => New_Occurrence_Of (Standard_Boolean, Loc)),

          Declarations => New_List (
            Make_Object_Declaration (Loc,
              Defining_Identifier => J,
              Object_Definition   => New_Occurrence_Of (Index, Loc),
              Expression =>
                Make_Attribute_Reference (Loc,
                  Prefix => New_Occurrence_Of (Y, Loc),
                  Attribute_Name => Name_First))),

          Handled_Statement_Sequence =>
            Make_Handled_Sequence_Of_Statements (Loc,
              Statements => New_List (If_Stat)));

      return Func_Body;
   end Make_Array_Comparison_Op;

   ---------------------------
   -- Make_Boolean_Array_Op --
   ---------------------------

   --  For logical operations on boolean arrays, expand in line the following,
   --  replacing 'and' with 'or' or 'xor' where needed:

   --    function Annn (A : typ; B: typ) return typ is
   --       C : typ;
   --    begin
   --       for J in A'range loop
   --          C (J) := A (J) op B (J);
   --       end loop;
   --       return C;
   --    end Annn;

   --  Here typ is the boolean array type

   function Make_Boolean_Array_Op
     (Typ : Entity_Id;
      N   : Node_Id) return Node_Id
   is
      Loc : constant Source_Ptr := Sloc (N);

      A : constant Entity_Id := Make_Defining_Identifier (Loc, Name_uA);
      B : constant Entity_Id := Make_Defining_Identifier (Loc, Name_uB);
      C : constant Entity_Id := Make_Defining_Identifier (Loc, Name_uC);
      J : constant Entity_Id := Make_Defining_Identifier (Loc, Name_uJ);

      A_J : Node_Id;
      B_J : Node_Id;
      C_J : Node_Id;
      Op  : Node_Id;

      Formals        : List_Id;
      Func_Name      : Entity_Id;
      Func_Body      : Node_Id;
      Loop_Statement : Node_Id;

   begin
      A_J :=
        Make_Indexed_Component (Loc,
          Prefix      => New_Occurrence_Of (A, Loc),
          Expressions => New_List (New_Occurrence_Of (J, Loc)));

      B_J :=
        Make_Indexed_Component (Loc,
          Prefix      => New_Occurrence_Of (B, Loc),
          Expressions => New_List (New_Occurrence_Of (J, Loc)));

      C_J :=
        Make_Indexed_Component (Loc,
          Prefix      => New_Occurrence_Of (C, Loc),
          Expressions => New_List (New_Occurrence_Of (J, Loc)));

      if Nkind (N) = N_Op_And then
         Op :=
           Make_Op_And (Loc,
             Left_Opnd  => A_J,
             Right_Opnd => B_J);

      elsif Nkind (N) = N_Op_Or then
         Op :=
           Make_Op_Or (Loc,
             Left_Opnd  => A_J,
             Right_Opnd => B_J);

      else
         Op :=
           Make_Op_Xor (Loc,
             Left_Opnd  => A_J,
             Right_Opnd => B_J);
      end if;

      Loop_Statement :=
        Make_Implicit_Loop_Statement (N,
          Identifier => Empty,

          Iteration_Scheme =>
            Make_Iteration_Scheme (Loc,
              Loop_Parameter_Specification =>
                Make_Loop_Parameter_Specification (Loc,
                  Defining_Identifier => J,
                  Discrete_Subtype_Definition =>
                    Make_Attribute_Reference (Loc,
                      Prefix => New_Occurrence_Of (A, Loc),
                      Attribute_Name => Name_Range))),

          Statements => New_List (
            Make_Assignment_Statement (Loc,
              Name       => C_J,
              Expression => Op)));

      Formals := New_List (
        Make_Parameter_Specification (Loc,
          Defining_Identifier => A,
          Parameter_Type      => New_Occurrence_Of (Typ, Loc)),

        Make_Parameter_Specification (Loc,
          Defining_Identifier => B,
          Parameter_Type      => New_Occurrence_Of (Typ, Loc)));

      Func_Name := Make_Temporary (Loc, 'A');
      Set_Is_Inlined (Func_Name);

      Func_Body :=
        Make_Subprogram_Body (Loc,
          Specification =>
            Make_Function_Specification (Loc,
              Defining_Unit_Name       => Func_Name,
              Parameter_Specifications => Formals,
              Result_Definition        => New_Occurrence_Of (Typ, Loc)),

          Declarations => New_List (
            Make_Object_Declaration (Loc,
              Defining_Identifier => C,
              Object_Definition   => New_Occurrence_Of (Typ, Loc))),

          Handled_Statement_Sequence =>
            Make_Handled_Sequence_Of_Statements (Loc,
              Statements => New_List (
                Loop_Statement,
                Make_Simple_Return_Statement (Loc,
                  Expression => New_Occurrence_Of (C, Loc)))));

      return Func_Body;
   end Make_Boolean_Array_Op;

   -----------------------------------------
   -- Minimized_Eliminated_Overflow_Check --
   -----------------------------------------

   function Minimized_Eliminated_Overflow_Check (N : Node_Id) return Boolean is
   begin
      return
        Is_Signed_Integer_Type (Etype (N))
          and then Overflow_Check_Mode in Minimized_Or_Eliminated;
   end Minimized_Eliminated_Overflow_Check;

   --------------------------------
   -- Optimize_Length_Comparison --
   --------------------------------

   procedure Optimize_Length_Comparison (N : Node_Id) is
      Loc    : constant Source_Ptr := Sloc (N);
      Typ    : constant Entity_Id  := Etype (N);
      Result : Node_Id;

      Left  : Node_Id;
      Right : Node_Id;
      --  First and Last attribute reference nodes, which end up as left and
      --  right operands of the optimized result.

      Is_Zero : Boolean;
      --  True for comparison operand of zero

      Comp : Node_Id;
      --  Comparison operand, set only if Is_Zero is false

      Ent : Entity_Id := Empty;
      --  Entity whose length is being compared

      Index : Node_Id := Empty;
      --  Integer_Literal node for length attribute expression, or Empty
      --  if there is no such expression present.

      Ityp  : Entity_Id;
      --  Type of array index to which 'Length is applied

      Op : Node_Kind := Nkind (N);
      --  Kind of comparison operator, gets flipped if operands backwards

      function Is_Optimizable (N : Node_Id) return Boolean;
      --  Tests N to see if it is an optimizable comparison value (defined as
      --  constant zero or one, or something else where the value is known to
      --  be positive and in the range of 32-bits, and where the corresponding
      --  Length value is also known to be 32-bits. If result is true, sets
      --  Is_Zero, Ityp, and Comp accordingly.

      function Is_Entity_Length (N : Node_Id) return Boolean;
      --  Tests if N is a length attribute applied to a simple entity. If so,
      --  returns True, and sets Ent to the entity, and Index to the integer
      --  literal provided as an attribute expression, or to Empty if none.
      --  Also returns True if the expression is a generated type conversion
      --  whose expression is of the desired form. This latter case arises
      --  when Apply_Universal_Integer_Attribute_Check installs a conversion
      --  to check for being in range, which is not needed in this context.
      --  Returns False if neither condition holds.

      function Prepare_64 (N : Node_Id) return Node_Id;
      --  Given a discrete expression, returns a Long_Long_Integer typed
      --  expression representing the underlying value of the expression.
      --  This is done with an unchecked conversion to the result type. We
      --  use unchecked conversion to handle the enumeration type case.

      ----------------------
      -- Is_Entity_Length --
      ----------------------

      function Is_Entity_Length (N : Node_Id) return Boolean is
      begin
         if Nkind (N) = N_Attribute_Reference
           and then Attribute_Name (N) = Name_Length
           and then Is_Entity_Name (Prefix (N))
         then
            Ent := Entity (Prefix (N));

            if Present (Expressions (N)) then
               Index := First (Expressions (N));
            else
               Index := Empty;
            end if;

            return True;

         elsif Nkind (N) = N_Type_Conversion
           and then not Comes_From_Source (N)
         then
            return Is_Entity_Length (Expression (N));

         else
            return False;
         end if;
      end Is_Entity_Length;

      --------------------
      -- Is_Optimizable --
      --------------------

      function Is_Optimizable (N : Node_Id) return Boolean is
         Val  : Uint;
         OK   : Boolean;
         Lo   : Uint;
         Hi   : Uint;
         Indx : Node_Id;

      begin
         if Compile_Time_Known_Value (N) then
            Val := Expr_Value (N);

            if Val = Uint_0 then
               Is_Zero := True;
               Comp    := Empty;
               return True;

            elsif Val = Uint_1 then
               Is_Zero := False;
               Comp    := Empty;
               return True;
            end if;
         end if;

         --  Here we have to make sure of being within 32-bits

         Determine_Range (N, OK, Lo, Hi, Assume_Valid => True);

         if not OK
           or else Lo < Uint_1
           or else Hi > UI_From_Int (Int'Last)
         then
            return False;
         end if;

         --  Comparison value was within range, so now we must check the index
         --  value to make sure it is also within 32-bits.

         Indx := First_Index (Etype (Ent));

         if Present (Index) then
            for J in 2 .. UI_To_Int (Intval (Index)) loop
               Next_Index (Indx);
            end loop;
         end if;

         Ityp := Etype (Indx);

         if Esize (Ityp) > 32 then
            return False;
         end if;

         Is_Zero := False;
         Comp := N;
         return True;
      end Is_Optimizable;

      ----------------
      -- Prepare_64 --
      ----------------

      function Prepare_64 (N : Node_Id) return Node_Id is
      begin
         return Unchecked_Convert_To (Standard_Long_Long_Integer, N);
      end Prepare_64;

   --  Start of processing for Optimize_Length_Comparison

   begin
      --  Nothing to do if not a comparison

      if Op not in N_Op_Compare then
         return;
      end if;

      --  Nothing to do if special -gnatd.P debug flag set.

      if Debug_Flag_Dot_PP then
         return;
      end if;

      --  Ent'Length op 0/1

      if Is_Entity_Length (Left_Opnd (N))
        and then Is_Optimizable (Right_Opnd (N))
      then
         null;

      --  0/1 op Ent'Length

      elsif Is_Entity_Length (Right_Opnd (N))
        and then Is_Optimizable (Left_Opnd (N))
      then
         --  Flip comparison to opposite sense

         case Op is
            when N_Op_Lt => Op := N_Op_Gt;
            when N_Op_Le => Op := N_Op_Ge;
            when N_Op_Gt => Op := N_Op_Lt;
            when N_Op_Ge => Op := N_Op_Le;
            when others  => null;
         end case;

      --  Else optimization not possible

      else
         return;
      end if;

      --  Fall through if we will do the optimization

      --  Cases to handle:

      --    X'Length = 0  => X'First > X'Last
      --    X'Length = 1  => X'First = X'Last
      --    X'Length = n  => X'First + (n - 1) = X'Last

      --    X'Length /= 0 => X'First <= X'Last
      --    X'Length /= 1 => X'First /= X'Last
      --    X'Length /= n => X'First + (n - 1) /= X'Last

      --    X'Length >= 0 => always true, warn
      --    X'Length >= 1 => X'First <= X'Last
      --    X'Length >= n => X'First + (n - 1) <= X'Last

      --    X'Length > 0  => X'First <= X'Last
      --    X'Length > 1  => X'First < X'Last
      --    X'Length > n  => X'First + (n - 1) < X'Last

      --    X'Length <= 0 => X'First > X'Last (warn, could be =)
      --    X'Length <= 1 => X'First >= X'Last
      --    X'Length <= n => X'First + (n - 1) >= X'Last

      --    X'Length < 0  => always false (warn)
      --    X'Length < 1  => X'First > X'Last
      --    X'Length < n  => X'First + (n - 1) > X'Last

      --  Note: for the cases of n (not constant 0,1), we require that the
      --  corresponding index type be integer or shorter (i.e. not 64-bit),
      --  and the same for the comparison value. Then we do the comparison
      --  using 64-bit arithmetic (actually long long integer), so that we
      --  cannot have overflow intefering with the result.

      --  First deal with warning cases

      if Is_Zero then
         case Op is

            --  X'Length >= 0

            when N_Op_Ge =>
               Rewrite (N,
                 Convert_To (Typ, New_Occurrence_Of (Standard_True, Loc)));
               Analyze_And_Resolve (N, Typ);
               Warn_On_Known_Condition (N);
               return;

            --  X'Length < 0

            when N_Op_Lt =>
               Rewrite (N,
                 Convert_To (Typ, New_Occurrence_Of (Standard_False, Loc)));
               Analyze_And_Resolve (N, Typ);
               Warn_On_Known_Condition (N);
               return;

            when N_Op_Le =>
               if Constant_Condition_Warnings
                 and then Comes_From_Source (Original_Node (N))
               then
                  Error_Msg_N ("could replace by ""'=""?c?", N);
               end if;

               Op := N_Op_Eq;

            when others =>
               null;
         end case;
      end if;

      --  Build the First reference we will use

      Left :=
        Make_Attribute_Reference (Loc,
          Prefix         => New_Occurrence_Of (Ent, Loc),
          Attribute_Name => Name_First);

      if Present (Index) then
         Set_Expressions (Left, New_List (New_Copy (Index)));
      end if;

      --  If general value case, then do the addition of (n - 1), and
      --  also add the needed conversions to type Long_Long_Integer.

      if Present (Comp) then
         Left :=
           Make_Op_Add (Loc,
             Left_Opnd  => Prepare_64 (Left),
             Right_Opnd =>
               Make_Op_Subtract (Loc,
                 Left_Opnd  => Prepare_64 (Comp),
                 Right_Opnd => Make_Integer_Literal (Loc, 1)));
      end if;

      --  Build the Last reference we will use

      Right :=
        Make_Attribute_Reference (Loc,
          Prefix         => New_Occurrence_Of (Ent, Loc),
          Attribute_Name => Name_Last);

      if Present (Index) then
         Set_Expressions (Right, New_List (New_Copy (Index)));
      end if;

      --  If general operand, convert Last reference to Long_Long_Integer

      if Present (Comp) then
         Right := Prepare_64 (Right);
      end if;

      --  Check for cases to optimize

      --  X'Length = 0  => X'First > X'Last
      --  X'Length < 1  => X'First > X'Last
      --  X'Length < n  => X'First + (n - 1) > X'Last

      if (Is_Zero and then Op = N_Op_Eq)
        or else (not Is_Zero and then Op = N_Op_Lt)
      then
         Result :=
           Make_Op_Gt (Loc,
             Left_Opnd  => Left,
             Right_Opnd => Right);

      --  X'Length = 1  => X'First = X'Last
      --  X'Length = n  => X'First + (n - 1) = X'Last

      elsif not Is_Zero and then Op = N_Op_Eq then
         Result :=
           Make_Op_Eq (Loc,
             Left_Opnd  => Left,
             Right_Opnd => Right);

      --  X'Length /= 0 => X'First <= X'Last
      --  X'Length > 0  => X'First <= X'Last

      elsif Is_Zero and (Op = N_Op_Ne or else Op = N_Op_Gt) then
         Result :=
           Make_Op_Le (Loc,
             Left_Opnd  => Left,
             Right_Opnd => Right);

      --  X'Length /= 1 => X'First /= X'Last
      --  X'Length /= n => X'First + (n - 1) /= X'Last

      elsif not Is_Zero and then Op = N_Op_Ne then
         Result :=
           Make_Op_Ne (Loc,
             Left_Opnd  => Left,
             Right_Opnd => Right);

      --  X'Length >= 1 => X'First <= X'Last
      --  X'Length >= n => X'First + (n - 1) <= X'Last

      elsif not Is_Zero and then Op = N_Op_Ge then
         Result :=
           Make_Op_Le (Loc,
             Left_Opnd  => Left,
             Right_Opnd => Right);

      --  X'Length > 1  => X'First < X'Last
      --  X'Length > n  => X'First + (n = 1) < X'Last

      elsif not Is_Zero and then Op = N_Op_Gt then
         Result :=
           Make_Op_Lt (Loc,
             Left_Opnd  => Left,
             Right_Opnd => Right);

      --  X'Length <= 1 => X'First >= X'Last
      --  X'Length <= n => X'First + (n - 1) >= X'Last

      elsif not Is_Zero and then Op = N_Op_Le then
         Result :=
           Make_Op_Ge (Loc,
             Left_Opnd  => Left,
             Right_Opnd => Right);

      --  Should not happen at this stage

      else
         raise Program_Error;
      end if;

      --  Rewrite and finish up

      Rewrite (N, Result);
      Analyze_And_Resolve (N, Typ);
      return;
   end Optimize_Length_Comparison;

   --------------------------------
   -- Process_If_Case_Statements --
   --------------------------------

   procedure Process_If_Case_Statements (N : Node_Id; Stmts : List_Id) is
      Decl : Node_Id;

   begin
      Decl := First (Stmts);
      while Present (Decl) loop
         if Nkind (Decl) = N_Object_Declaration
           and then Is_Finalizable_Transient (Decl, N)
         then
            Process_Transient_In_Expression (Decl, N, Stmts);
         end if;

         Next (Decl);
      end loop;
   end Process_If_Case_Statements;

   -------------------------------------
   -- Process_Transient_In_Expression --
   -------------------------------------

   procedure Process_Transient_In_Expression
     (Obj_Decl : Node_Id;
      Expr     : Node_Id;
      Stmts    : List_Id)
   is
      Loc    : constant Source_Ptr := Sloc (Obj_Decl);
      Obj_Id : constant Entity_Id  := Defining_Identifier (Obj_Decl);

      Hook_Context : constant Node_Id := Find_Hook_Context (Expr);
      --  The node on which to insert the hook as an action. This is usually
      --  the innermost enclosing non-transient construct.

      Fin_Call    : Node_Id;
      Hook_Assign : Node_Id;
      Hook_Clear  : Node_Id;
      Hook_Decl   : Node_Id;
      Hook_Insert : Node_Id;
      Ptr_Decl    : Node_Id;

      Fin_Context : Node_Id;
      --  The node after which to insert the finalization actions of the
      --  transient object.

   begin
      pragma Assert (Nkind_In (Expr, N_Case_Expression,
                                     N_Expression_With_Actions,
                                     N_If_Expression));

      --  When the context is a Boolean evaluation, all three nodes capture the
      --  result of their computation in a local temporary:

      --    do
      --       Trans_Id : Ctrl_Typ := ...;
      --       Result : constant Boolean := ... Trans_Id ...;
      --       <finalize Trans_Id>
      --    in Result end;

      --  As a result, the finalization of any transient objects can safely
      --  take place after the result capture.

      --  ??? could this be extended to elementary types?

      if Is_Boolean_Type (Etype (Expr)) then
         Fin_Context := Last (Stmts);

      --  Otherwise the immediate context may not be safe enough to carry
      --  out transient object finalization due to aliasing and nesting of
      --  constructs. Insert calls to [Deep_]Finalize after the innermost
      --  enclosing non-transient construct.

      else
         Fin_Context := Hook_Context;
      end if;

      --  Mark the transient object as successfully processed to avoid double
      --  finalization.

      Set_Is_Finalized_Transient (Obj_Id);

      --  Construct all the pieces necessary to hook and finalize a transient
      --  object.

      Build_Transient_Object_Statements
        (Obj_Decl     => Obj_Decl,
         Fin_Call     => Fin_Call,
         Hook_Assign  => Hook_Assign,
         Hook_Clear   => Hook_Clear,
         Hook_Decl    => Hook_Decl,
         Ptr_Decl     => Ptr_Decl,
         Finalize_Obj => False);

      --  Add the access type which provides a reference to the transient
      --  object. Generate:

      --    type Ptr_Typ is access all Desig_Typ;

      Insert_Action (Hook_Context, Ptr_Decl);

      --  Add the temporary which acts as a hook to the transient object.
      --  Generate:

      --    Hook : Ptr_Id := null;

      Insert_Action (Hook_Context, Hook_Decl);

      --  When the transient object is initialized by an aggregate, the hook
      --  must capture the object after the last aggregate assignment takes
      --  place. Only then is the object considered initialized. Generate:

      --    Hook := Ptr_Typ (Obj_Id);
      --      <or>
      --    Hook := Obj_Id'Unrestricted_Access;

      if Ekind_In (Obj_Id, E_Constant, E_Variable)
        and then Present (Last_Aggregate_Assignment (Obj_Id))
      then
         Hook_Insert := Last_Aggregate_Assignment (Obj_Id);

      --  Otherwise the hook seizes the related object immediately

      else
         Hook_Insert := Obj_Decl;
      end if;

      Insert_After_And_Analyze (Hook_Insert, Hook_Assign);

      --  When the node is part of a return statement, there is no need to
      --  insert a finalization call, as the general finalization mechanism
      --  (see Build_Finalizer) would take care of the transient object on
      --  subprogram exit. Note that it would also be impossible to insert the
      --  finalization code after the return statement as this will render it
      --  unreachable.

      if Nkind (Fin_Context) = N_Simple_Return_Statement then
         null;

      --  Finalize the hook after the context has been evaluated. Generate:

      --    if Hook /= null then
      --       [Deep_]Finalize (Hook.all);
      --       Hook := null;
      --    end if;

      else
         Insert_Action_After (Fin_Context,
           Make_Implicit_If_Statement (Obj_Decl,
             Condition =>
               Make_Op_Ne (Loc,
                 Left_Opnd  =>
                   New_Occurrence_Of (Defining_Entity (Hook_Decl), Loc),
                 Right_Opnd => Make_Null (Loc)),

             Then_Statements => New_List (
               Fin_Call,
               Hook_Clear)));
      end if;
   end Process_Transient_In_Expression;

   ------------------------
   -- Rewrite_Comparison --
   ------------------------

   procedure Rewrite_Comparison (N : Node_Id) is
      Typ : constant Entity_Id := Etype (N);

      False_Result : Boolean;
      True_Result  : Boolean;

   begin
      if Nkind (N) = N_Type_Conversion then
         Rewrite_Comparison (Expression (N));
         return;

      elsif Nkind (N) not in N_Op_Compare then
         return;
      end if;

      --  Determine the potential outcome of the comparison assuming that the
      --  operands are valid and emit a warning when the comparison evaluates
      --  to True or False only in the presence of invalid values.

      Warn_On_Constant_Valid_Condition (N);

      --  Determine the potential outcome of the comparison assuming that the
      --  operands are not valid.

      Test_Comparison
        (Op           => N,
         Assume_Valid => False,
         True_Result  => True_Result,
         False_Result => False_Result);

      --  The outcome is a decisive False or True, rewrite the operator

      if False_Result or True_Result then
         Rewrite (N,
           Convert_To (Typ,
             New_Occurrence_Of (Boolean_Literals (True_Result), Sloc (N))));

         Analyze_And_Resolve (N, Typ);
         Warn_On_Known_Condition (N);
      end if;
   end Rewrite_Comparison;

   ----------------------------
   -- Safe_In_Place_Array_Op --
   ----------------------------

   function Safe_In_Place_Array_Op
     (Lhs : Node_Id;
      Op1 : Node_Id;
      Op2 : Node_Id) return Boolean
   is
      Target : Entity_Id;

      function Is_Safe_Operand (Op : Node_Id) return Boolean;
      --  Operand is safe if it cannot overlap part of the target of the
      --  operation. If the operand and the target are identical, the operand
      --  is safe. The operand can be empty in the case of negation.

      function Is_Unaliased (N : Node_Id) return Boolean;
      --  Check that N is a stand-alone entity

      ------------------
      -- Is_Unaliased --
      ------------------

      function Is_Unaliased (N : Node_Id) return Boolean is
      begin
         return
           Is_Entity_Name (N)
             and then No (Address_Clause (Entity (N)))
             and then No (Renamed_Object (Entity (N)));
      end Is_Unaliased;

      ---------------------
      -- Is_Safe_Operand --
      ---------------------

      function Is_Safe_Operand (Op : Node_Id) return Boolean is
      begin
         if No (Op) then
            return True;

         elsif Is_Entity_Name (Op) then
            return Is_Unaliased (Op);

         elsif Nkind_In (Op, N_Indexed_Component, N_Selected_Component) then
            return Is_Unaliased (Prefix (Op));

         elsif Nkind (Op) = N_Slice then
            return
              Is_Unaliased (Prefix (Op))
                and then Entity (Prefix (Op)) /= Target;

         elsif Nkind (Op) = N_Op_Not then
            return Is_Safe_Operand (Right_Opnd (Op));

         else
            return False;
         end if;
      end Is_Safe_Operand;

   --  Start of processing for Safe_In_Place_Array_Op

   begin
      --  Skip this processing if the component size is different from system
      --  storage unit (since at least for NOT this would cause problems).

      if Component_Size (Etype (Lhs)) /= System_Storage_Unit then
         return False;

      --  Cannot do in place stuff if non-standard Boolean representation

      elsif Has_Non_Standard_Rep (Component_Type (Etype (Lhs))) then
         return False;

      elsif not Is_Unaliased (Lhs) then
         return False;

      else
         Target := Entity (Lhs);
         return Is_Safe_Operand (Op1) and then Is_Safe_Operand (Op2);
      end if;
   end Safe_In_Place_Array_Op;

   -----------------------
   -- Tagged_Membership --
   -----------------------

   --  There are two different cases to consider depending on whether the right
   --  operand is a class-wide type or not. If not we just compare the actual
   --  tag of the left expr to the target type tag:
   --
   --     Left_Expr.Tag = Right_Type'Tag;
   --
   --  If it is a class-wide type we use the RT function CW_Membership which is
   --  usually implemented by looking in the ancestor tables contained in the
   --  dispatch table pointed by Left_Expr.Tag for Typ'Tag

   --  Ada 2005 (AI-251): If it is a class-wide interface type we use the RT
   --  function IW_Membership which is usually implemented by looking in the
   --  table of abstract interface types plus the ancestor table contained in
   --  the dispatch table pointed by Left_Expr.Tag for Typ'Tag

   procedure Tagged_Membership
     (N         : Node_Id;
      SCIL_Node : out Node_Id;
      Result    : out Node_Id)
   is
      Left  : constant Node_Id    := Left_Opnd  (N);
      Right : constant Node_Id    := Right_Opnd (N);
      Loc   : constant Source_Ptr := Sloc (N);

      Full_R_Typ : Entity_Id;
      Left_Type  : Entity_Id;
      New_Node   : Node_Id;
      Right_Type : Entity_Id;
      Obj_Tag    : Node_Id;

   begin
      SCIL_Node := Empty;

      --  Handle entities from the limited view

      Left_Type  := Available_View (Etype (Left));
      Right_Type := Available_View (Etype (Right));

      --  In the case where the type is an access type, the test is applied
      --  using the designated types (needed in Ada 2012 for implicit anonymous
      --  access conversions, for AI05-0149).

      if Is_Access_Type (Right_Type) then
         Left_Type  := Designated_Type (Left_Type);
         Right_Type := Designated_Type (Right_Type);
      end if;

      if Is_Class_Wide_Type (Left_Type) then
         Left_Type := Root_Type (Left_Type);
      end if;

      if Is_Class_Wide_Type (Right_Type) then
         Full_R_Typ := Underlying_Type (Root_Type (Right_Type));
      else
         Full_R_Typ := Underlying_Type (Right_Type);
      end if;

      Obj_Tag :=
        Make_Selected_Component (Loc,
          Prefix        => Relocate_Node (Left),
          Selector_Name =>
            New_Occurrence_Of (First_Tag_Component (Left_Type), Loc));

      if Is_Class_Wide_Type (Right_Type) or else Is_Interface (Left_Type) then

         --  No need to issue a run-time check if we statically know that the
         --  result of this membership test is always true. For example,
         --  considering the following declarations:

         --    type Iface is interface;
         --    type T     is tagged null record;
         --    type DT    is new T and Iface with null record;

         --    Obj1 : T;
         --    Obj2 : DT;

         --  These membership tests are always true:

         --    Obj1 in T'Class
         --    Obj2 in T'Class;
         --    Obj2 in Iface'Class;

         --  We do not need to handle cases where the membership is illegal.
         --  For example:

         --    Obj1 in DT'Class;     --  Compile time error
         --    Obj1 in Iface'Class;  --  Compile time error

         if not Is_Interface (Left_Type)
           and then not Is_Class_Wide_Type (Left_Type)
           and then (Is_Ancestor (Etype (Right_Type), Left_Type,
                                  Use_Full_View => True)
                      or else (Is_Interface (Etype (Right_Type))
                                and then Interface_Present_In_Ancestor
                                           (Typ   => Left_Type,
                                            Iface => Etype (Right_Type))))
         then
            Result := New_Occurrence_Of (Standard_True, Loc);
            return;
         end if;

         --  Ada 2005 (AI-251): Class-wide applied to interfaces

         if Is_Interface (Etype (Class_Wide_Type (Right_Type)))

            --   Support to: "Iface_CW_Typ in Typ'Class"

           or else Is_Interface (Left_Type)
         then
            --  Issue error if IW_Membership operation not available in a
            --  configurable run time setting.

            if not RTE_Available (RE_IW_Membership) then
               Error_Msg_CRT
                 ("dynamic membership test on interface types", N);
               Result := Empty;
               return;
            end if;

            Result :=
              Make_Function_Call (Loc,
                 Name => New_Occurrence_Of (RTE (RE_IW_Membership), Loc),
                 Parameter_Associations => New_List (
                   Make_Attribute_Reference (Loc,
                     Prefix => Obj_Tag,
                     Attribute_Name => Name_Address),
                   New_Occurrence_Of (
                     Node (First_Elmt (Access_Disp_Table (Full_R_Typ))),
                     Loc)));

         --  Ada 95: Normal case

         else
            Build_CW_Membership (Loc,
              Obj_Tag_Node => Obj_Tag,
              Typ_Tag_Node =>
                 New_Occurrence_Of (
                   Node (First_Elmt (Access_Disp_Table (Full_R_Typ))),  Loc),
              Related_Nod => N,
              New_Node    => New_Node);

            --  Generate the SCIL node for this class-wide membership test.
            --  Done here because the previous call to Build_CW_Membership
            --  relocates Obj_Tag.

            if Generate_SCIL then
               SCIL_Node := Make_SCIL_Membership_Test (Sloc (N));
               Set_SCIL_Entity (SCIL_Node, Etype (Right_Type));
               Set_SCIL_Tag_Value (SCIL_Node, Obj_Tag);
            end if;

            Result := New_Node;
         end if;

      --  Right_Type is not a class-wide type

      else
         --  No need to check the tag of the object if Right_Typ is abstract

         if Is_Abstract_Type (Right_Type) then
            Result := New_Occurrence_Of (Standard_False, Loc);

         else
            Result :=
              Make_Op_Eq (Loc,
                Left_Opnd  => Obj_Tag,
                Right_Opnd =>
                  New_Occurrence_Of
                    (Node (First_Elmt (Access_Disp_Table (Full_R_Typ))), Loc));
         end if;
      end if;
   end Tagged_Membership;

   ------------------------------
   -- Unary_Op_Validity_Checks --
   ------------------------------

   procedure Unary_Op_Validity_Checks (N : Node_Id) is
   begin
      if Validity_Checks_On and Validity_Check_Operands then
         Ensure_Valid (Right_Opnd (N));
      end if;
   end Unary_Op_Validity_Checks;

end Exp_Ch4;
