------------------------------------------------------------------------------
--                                                                          --
--                         GNAT COMPILER COMPONENTS                         --
--                                                                          --
--                              S E M _ R E S                               --
--                                                                          --
--                                 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 Debug_A;  use Debug_A;
with Einfo;    use Einfo;
with Errout;   use Errout;
with Expander; use Expander;
with Exp_Ch6;  use Exp_Ch6;
with Exp_Ch7;  use Exp_Ch7;
with Exp_Disp; use Exp_Disp;
with Exp_Tss;  use Exp_Tss;
with Exp_Util; use Exp_Util;
with Freeze;   use Freeze;
with Ghost;    use Ghost;
with Inline;   use Inline;
with Itypes;   use Itypes;
with Lib;      use Lib;
with Lib.Xref; use Lib.Xref;
with Namet;    use Namet;
with Nmake;    use Nmake;
with Nlists;   use Nlists;
with Opt;      use Opt;
with Output;   use Output;
with Par_SCO;  use Par_SCO;
with Restrict; use Restrict;
with Rident;   use Rident;
with Rtsfind;  use Rtsfind;
with Sem;      use Sem;
with Sem_Aggr; use Sem_Aggr;
with Sem_Attr; use Sem_Attr;
with Sem_Aux;  use Sem_Aux;
with Sem_Cat;  use Sem_Cat;
with Sem_Ch3;  use Sem_Ch3;
with Sem_Ch4;  use Sem_Ch4;
with Sem_Ch6;  use Sem_Ch6;
with Sem_Ch8;  use Sem_Ch8;
with Sem_Ch13; use Sem_Ch13;
with Sem_Dim;  use Sem_Dim;
with Sem_Disp; use Sem_Disp;
with Sem_Dist; use Sem_Dist;
with Sem_Elab; use Sem_Elab;
with Sem_Elim; use Sem_Elim;
with Sem_Eval; use Sem_Eval;
with Sem_Intr; use Sem_Intr;
with Sem_Mech; use Sem_Mech;
with Sem_Type; use Sem_Type;
with Sem_Util; use Sem_Util;
with Sem_Warn; use Sem_Warn;
with Sinfo;    use Sinfo;
with Sinfo.CN; use Sinfo.CN;
with Snames;   use Snames;
with Stand;    use Stand;
with Stringt;  use Stringt;
with Style;    use Style;
with Targparm; use Targparm;
with Tbuild;   use Tbuild;
with Uintp;    use Uintp;
with Urealp;   use Urealp;

package body Sem_Res is

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

   --  Second pass (top-down) type checking and overload resolution procedures
   --  Typ is the type required by context. These procedures propagate the
   --  type information recursively to the descendants of N. If the node is not
   --  overloaded, its Etype is established in the first pass. If overloaded,
   --  the Resolve routines set the correct type. For arithmetic operators, the
   --  Etype is the base type of the context.

   --  Note that Resolve_Attribute is separated off in Sem_Attr

   procedure Check_Discriminant_Use (N : Node_Id);
   --  Enforce the restrictions on the use of discriminants when constraining
   --  a component of a discriminated type (record or concurrent type).

   procedure Check_For_Visible_Operator (N : Node_Id; T : Entity_Id);
   --  Given a node for an operator associated with type T, check that the
   --  operator is visible. Operators all of whose operands are universal must
   --  be checked for visibility during resolution because their type is not
   --  determinable based on their operands.

   procedure Check_Fully_Declared_Prefix
     (Typ  : Entity_Id;
      Pref : Node_Id);
   --  Check that the type of the prefix of a dereference is not incomplete

   function Check_Infinite_Recursion (Call : Node_Id) return Boolean;
   --  Given a call node, Call, which is known to occur immediately within the
   --  subprogram being called, determines whether it is a detectable case of
   --  an infinite recursion, and if so, outputs appropriate messages. Returns
   --  True if an infinite recursion is detected, and False otherwise.

   procedure Check_No_Direct_Boolean_Operators (N : Node_Id);
   --  N is the node for a logical operator. If the operator is predefined, and
   --  the root type of the operands is Standard.Boolean, then a check is made
   --  for restriction No_Direct_Boolean_Operators. This procedure also handles
   --  the style check for Style_Check_Boolean_And_Or.

   function Is_Atomic_Ref_With_Address (N : Node_Id) return Boolean;
   --  N is either an indexed component or a selected component. This function
   --  returns true if the prefix refers to an object that has an address
   --  clause (the case in which we may want to issue a warning).

   function Is_Definite_Access_Type (E : Entity_Id) return Boolean;
   --  Determine whether E is an access type declared by an access declaration,
   --  and not an (anonymous) allocator type.

   function Is_Predefined_Op (Nam : Entity_Id) return Boolean;
   --  Utility to check whether the entity for an operator is a predefined
   --  operator, in which case the expression is left as an operator in the
   --  tree (else it is rewritten into a call). An instance of an intrinsic
   --  conversion operation may be given an operator name, but is not treated
   --  like an operator. Note that an operator that is an imported back-end
   --  builtin has convention Intrinsic, but is expected to be rewritten into
   --  a call, so such an operator is not treated as predefined by this
   --  predicate.

   procedure Preanalyze_And_Resolve
     (N             : Node_Id;
      T             : Entity_Id;
      With_Freezing : Boolean);
   --  Subsidiary of public versions of Preanalyze_And_Resolve.

   procedure Replace_Actual_Discriminants (N : Node_Id; Default : Node_Id);
   --  If a default expression in entry call N depends on the discriminants
   --  of the task, it must be replaced with a reference to the discriminant
   --  of the task being called.

   procedure Resolve_Op_Concat_Arg
     (N       : Node_Id;
      Arg     : Node_Id;
      Typ     : Entity_Id;
      Is_Comp : Boolean);
   --  Internal procedure for Resolve_Op_Concat to resolve one operand of
   --  concatenation operator. The operand is either of the array type or of
   --  the component type. If the operand is an aggregate, and the component
   --  type is composite, this is ambiguous if component type has aggregates.

   procedure Resolve_Op_Concat_First (N : Node_Id; Typ : Entity_Id);
   --  Does the first part of the work of Resolve_Op_Concat

   procedure Resolve_Op_Concat_Rest (N : Node_Id; Typ : Entity_Id);
   --  Does the "rest" of the work of Resolve_Op_Concat, after the left operand
   --  has been resolved. See Resolve_Op_Concat for details.

   procedure Resolve_Allocator                 (N : Node_Id; Typ : Entity_Id);
   procedure Resolve_Arithmetic_Op             (N : Node_Id; Typ : Entity_Id);
   procedure Resolve_Call                      (N : Node_Id; Typ : Entity_Id);
   procedure Resolve_Case_Expression           (N : Node_Id; Typ : Entity_Id);
   procedure Resolve_Character_Literal         (N : Node_Id; Typ : Entity_Id);
   procedure Resolve_Comparison_Op             (N : Node_Id; Typ : Entity_Id);
   procedure Resolve_Entity_Name               (N : Node_Id; Typ : Entity_Id);
   procedure Resolve_Equality_Op               (N : Node_Id; Typ : Entity_Id);
   procedure Resolve_Explicit_Dereference      (N : Node_Id; Typ : Entity_Id);
   procedure Resolve_Expression_With_Actions   (N : Node_Id; Typ : Entity_Id);
   procedure Resolve_If_Expression             (N : Node_Id; Typ : Entity_Id);
   procedure Resolve_Generalized_Indexing      (N : Node_Id; Typ : Entity_Id);
   procedure Resolve_Indexed_Component         (N : Node_Id; Typ : Entity_Id);
   procedure Resolve_Integer_Literal           (N : Node_Id; Typ : Entity_Id);
   procedure Resolve_Logical_Op                (N : Node_Id; Typ : Entity_Id);
   procedure Resolve_Membership_Op             (N : Node_Id; Typ : Entity_Id);
   procedure Resolve_Null                      (N : Node_Id; Typ : Entity_Id);
   procedure Resolve_Operator_Symbol           (N : Node_Id; Typ : Entity_Id);
   procedure Resolve_Op_Concat                 (N : Node_Id; Typ : Entity_Id);
   procedure Resolve_Op_Expon                  (N : Node_Id; Typ : Entity_Id);
   procedure Resolve_Op_Not                    (N : Node_Id; Typ : Entity_Id);
   procedure Resolve_Qualified_Expression      (N : Node_Id; Typ : Entity_Id);
   procedure Resolve_Raise_Expression          (N : Node_Id; Typ : Entity_Id);
   procedure Resolve_Range                     (N : Node_Id; Typ : Entity_Id);
   procedure Resolve_Real_Literal              (N : Node_Id; Typ : Entity_Id);
   procedure Resolve_Reference                 (N : Node_Id; Typ : Entity_Id);
   procedure Resolve_Selected_Component        (N : Node_Id; Typ : Entity_Id);
   procedure Resolve_Shift                     (N : Node_Id; Typ : Entity_Id);
   procedure Resolve_Short_Circuit             (N : Node_Id; Typ : Entity_Id);
   procedure Resolve_Slice                     (N : Node_Id; Typ : Entity_Id);
   procedure Resolve_String_Literal            (N : Node_Id; Typ : Entity_Id);
   procedure Resolve_Target_Name               (N : Node_Id; Typ : Entity_Id);
   procedure Resolve_Type_Conversion           (N : Node_Id; Typ : Entity_Id);
   procedure Resolve_Unary_Op                  (N : Node_Id; Typ : Entity_Id);
   procedure Resolve_Unchecked_Expression      (N : Node_Id; Typ : Entity_Id);
   procedure Resolve_Unchecked_Type_Conversion (N : Node_Id; Typ : Entity_Id);

   function Operator_Kind
     (Op_Name   : Name_Id;
      Is_Binary : Boolean) return Node_Kind;
   --  Utility to map the name of an operator into the corresponding Node. Used
   --  by other node rewriting procedures.

   procedure Resolve_Actuals (N : Node_Id; Nam : Entity_Id);
   --  Resolve actuals of call, and add default expressions for missing ones.
   --  N is the Node_Id for the subprogram call, and Nam is the entity of the
   --  called subprogram.

   procedure Resolve_Entry_Call (N : Node_Id; Typ : Entity_Id);
   --  Called from Resolve_Call, when the prefix denotes an entry or element
   --  of entry family. Actuals are resolved as for subprograms, and the node
   --  is rebuilt as an entry call. Also called for protected operations. Typ
   --  is the context type, which is used when the operation is a protected
   --  function with no arguments, and the return value is indexed.

   procedure Resolve_Intrinsic_Operator (N : Node_Id; Typ : Entity_Id);
   --  A call to a user-defined intrinsic operator is rewritten as a call to
   --  the corresponding predefined operator, with suitable conversions. Note
   --  that this applies only for intrinsic operators that denote predefined
   --  operators, not ones that are intrinsic imports of back-end builtins.

   procedure Resolve_Intrinsic_Unary_Operator (N : Node_Id; Typ : Entity_Id);
   --  Ditto, for arithmetic unary operators

   procedure Rewrite_Operator_As_Call (N : Node_Id; Nam : Entity_Id);
   --  If an operator node resolves to a call to a user-defined operator,
   --  rewrite the node as a function call.

   procedure Make_Call_Into_Operator
     (N     : Node_Id;
      Typ   : Entity_Id;
      Op_Id : Entity_Id);
   --  Inverse transformation: if an operator is given in functional notation,
   --  then after resolving the node, transform into an operator node, so that
   --  operands are resolved properly. Recall that predefined operators do not
   --  have a full signature and special resolution rules apply.

   procedure Rewrite_Renamed_Operator
     (N   : Node_Id;
      Op  : Entity_Id;
      Typ : Entity_Id);
   --  An operator can rename another, e.g. in an instantiation. In that
   --  case, the proper operator node must be constructed and resolved.

   procedure Set_String_Literal_Subtype (N : Node_Id; Typ : Entity_Id);
   --  The String_Literal_Subtype is built for all strings that are not
   --  operands of a static concatenation operation. If the argument is not
   --  a N_String_Literal node, then the call has no effect.

   procedure Set_Slice_Subtype (N : Node_Id);
   --  Build subtype of array type, with the range specified by the slice

   procedure Simplify_Type_Conversion (N : Node_Id);
   --  Called after N has been resolved and evaluated, but before range checks
   --  have been applied. Currently simplifies a combination of floating-point
   --  to integer conversion and Rounding or Truncation attribute.

   function Unique_Fixed_Point_Type (N : Node_Id) return Entity_Id;
   --  A universal_fixed expression in an universal context is unambiguous if
   --  there is only one applicable fixed point type. Determining whether there
   --  is only one requires a search over all visible entities, and happens
   --  only in very pathological cases (see 6115-006).

   -------------------------
   -- Ambiguous_Character --
   -------------------------

   procedure Ambiguous_Character (C : Node_Id) is
      E : Entity_Id;

   begin
      if Nkind (C) = N_Character_Literal then
         Error_Msg_N ("ambiguous character literal", C);

         --  First the ones in Standard

         Error_Msg_N ("\\possible interpretation: Character!", C);
         Error_Msg_N ("\\possible interpretation: Wide_Character!", C);

         --  Include Wide_Wide_Character in Ada 2005 mode

         if Ada_Version >= Ada_2005 then
            Error_Msg_N ("\\possible interpretation: Wide_Wide_Character!", C);
         end if;

         --  Now any other types that match

         E := Current_Entity (C);
         while Present (E) loop
            Error_Msg_NE ("\\possible interpretation:}!", C, Etype (E));
            E := Homonym (E);
         end loop;
      end if;
   end Ambiguous_Character;

   -------------------------
   -- Analyze_And_Resolve --
   -------------------------

   procedure Analyze_And_Resolve (N : Node_Id) is
   begin
      Analyze (N);
      Resolve (N);
   end Analyze_And_Resolve;

   procedure Analyze_And_Resolve (N : Node_Id; Typ : Entity_Id) is
   begin
      Analyze (N);
      Resolve (N, Typ);
   end Analyze_And_Resolve;

   --  Versions with check(s) suppressed

   procedure Analyze_And_Resolve
     (N        : Node_Id;
      Typ      : Entity_Id;
      Suppress : Check_Id)
   is
      Scop : constant Entity_Id := Current_Scope;

   begin
      if Suppress = All_Checks then
         declare
            Sva : constant Suppress_Array := Scope_Suppress.Suppress;
         begin
            Scope_Suppress.Suppress := (others => True);
            Analyze_And_Resolve (N, Typ);
            Scope_Suppress.Suppress := Sva;
         end;

      else
         declare
            Svg : constant Boolean := Scope_Suppress.Suppress (Suppress);
         begin
            Scope_Suppress.Suppress (Suppress) := True;
            Analyze_And_Resolve (N, Typ);
            Scope_Suppress.Suppress (Suppress) := Svg;
         end;
      end if;

      if Current_Scope /= Scop
        and then Scope_Is_Transient
      then
         --  This can only happen if a transient scope was created for an inner
         --  expression, which will be removed upon completion of the analysis
         --  of an enclosing construct. The transient scope must have the
         --  suppress status of the enclosing environment, not of this Analyze
         --  call.

         Scope_Stack.Table (Scope_Stack.Last).Save_Scope_Suppress :=
           Scope_Suppress;
      end if;
   end Analyze_And_Resolve;

   procedure Analyze_And_Resolve
     (N        : Node_Id;
      Suppress : Check_Id)
   is
      Scop : constant Entity_Id := Current_Scope;

   begin
      if Suppress = All_Checks then
         declare
            Sva : constant Suppress_Array := Scope_Suppress.Suppress;
         begin
            Scope_Suppress.Suppress := (others => True);
            Analyze_And_Resolve (N);
            Scope_Suppress.Suppress := Sva;
         end;

      else
         declare
            Svg : constant Boolean := Scope_Suppress.Suppress (Suppress);
         begin
            Scope_Suppress.Suppress (Suppress) := True;
            Analyze_And_Resolve (N);
            Scope_Suppress.Suppress (Suppress) := Svg;
         end;
      end if;

      if Current_Scope /= Scop and then Scope_Is_Transient then
         Scope_Stack.Table (Scope_Stack.Last).Save_Scope_Suppress :=
           Scope_Suppress;
      end if;
   end Analyze_And_Resolve;

   ----------------------------
   -- Check_Discriminant_Use --
   ----------------------------

   procedure Check_Discriminant_Use (N : Node_Id) is
      PN   : constant Node_Id   := Parent (N);
      Disc : constant Entity_Id := Entity (N);
      P    : Node_Id;
      D    : Node_Id;

   begin
      --  Any use in a spec-expression is legal

      if In_Spec_Expression then
         null;

      elsif Nkind (PN) = N_Range then

         --  Discriminant cannot be used to constrain a scalar type

         P := Parent (PN);

         if Nkind (P) = N_Range_Constraint
           and then Nkind (Parent (P)) = N_Subtype_Indication
           and then Nkind (Parent (Parent (P))) = N_Component_Definition
         then
            Error_Msg_N ("discriminant cannot constrain scalar type", N);

         elsif Nkind (P) = N_Index_Or_Discriminant_Constraint then

            --  The following check catches the unusual case where a
            --  discriminant appears within an index constraint that is part
            --  of a larger expression within a constraint on a component,
            --  e.g. "C : Int range 1 .. F (new A(1 .. D))". For now we only
            --  check case of record components, and note that a similar check
            --  should also apply in the case of discriminant constraints
            --  below. ???

            --  Note that the check for N_Subtype_Declaration below is to
            --  detect the valid use of discriminants in the constraints of a
            --  subtype declaration when this subtype declaration appears
            --  inside the scope of a record type (which is syntactically
            --  illegal, but which may be created as part of derived type
            --  processing for records). See Sem_Ch3.Build_Derived_Record_Type
            --  for more info.

            if Ekind (Current_Scope) = E_Record_Type
              and then Scope (Disc) = Current_Scope
              and then not
                (Nkind (Parent (P)) = N_Subtype_Indication
                  and then
                    Nkind_In (Parent (Parent (P)), N_Component_Definition,
                                                   N_Subtype_Declaration)
                  and then Paren_Count (N) = 0)
            then
               Error_Msg_N
                 ("discriminant must appear alone in component constraint", N);
               return;
            end if;

            --   Detect a common error:

            --   type R (D : Positive := 100) is record
            --     Name : String (1 .. D);
            --   end record;

            --  The default value causes an object of type R to be allocated
            --  with room for Positive'Last characters. The RM does not mandate
            --  the allocation of the maximum size, but that is what GNAT does
            --  so we should warn the programmer that there is a problem.

            Check_Large : declare
               SI : Node_Id;
               T  : Entity_Id;
               TB : Node_Id;
               CB : Entity_Id;

               function Large_Storage_Type (T : Entity_Id) return Boolean;
               --  Return True if type T has a large enough range that any
               --  array whose index type covered the whole range of the type
               --  would likely raise Storage_Error.

               ------------------------
               -- Large_Storage_Type --
               ------------------------

               function Large_Storage_Type (T : Entity_Id) return Boolean is
               begin
                  --  The type is considered large if its bounds are known at
                  --  compile time and if it requires at least as many bits as
                  --  a Positive to store the possible values.

                  return Compile_Time_Known_Value (Type_Low_Bound (T))
                    and then Compile_Time_Known_Value (Type_High_Bound (T))
                    and then
                      Minimum_Size (T, Biased => True) >=
                        RM_Size (Standard_Positive);
               end Large_Storage_Type;

            --  Start of processing for Check_Large

            begin
               --  Check that the Disc has a large range

               if not Large_Storage_Type (Etype (Disc)) then
                  goto No_Danger;
               end if;

               --  If the enclosing type is limited, we allocate only the
               --  default value, not the maximum, and there is no need for
               --  a warning.

               if Is_Limited_Type (Scope (Disc)) then
                  goto No_Danger;
               end if;

               --  Check that it is the high bound

               if N /= High_Bound (PN)
                 or else No (Discriminant_Default_Value (Disc))
               then
                  goto No_Danger;
               end if;

               --  Check the array allows a large range at this bound. First
               --  find the array

               SI := Parent (P);

               if Nkind (SI) /= N_Subtype_Indication then
                  goto No_Danger;
               end if;

               T := Entity (Subtype_Mark (SI));

               if not Is_Array_Type (T) then
                  goto No_Danger;
               end if;

               --  Next, find the dimension

               TB := First_Index (T);
               CB := First (Constraints (P));
               while True
                 and then Present (TB)
                 and then Present (CB)
                 and then CB /= PN
               loop
                  Next_Index (TB);
                  Next (CB);
               end loop;

               if CB /= PN then
                  goto No_Danger;
               end if;

               --  Now, check the dimension has a large range

               if not Large_Storage_Type (Etype (TB)) then
                  goto No_Danger;
               end if;

               --  Warn about the danger

               Error_Msg_N
                 ("??creation of & object may raise Storage_Error!",
                  Scope (Disc));

               <<No_Danger>>
                  null;

            end Check_Large;
         end if;

      --  Legal case is in index or discriminant constraint

      elsif Nkind_In (PN, N_Index_Or_Discriminant_Constraint,
                          N_Discriminant_Association)
      then
         if Paren_Count (N) > 0 then
            Error_Msg_N
              ("discriminant in constraint must appear alone",  N);

         elsif Nkind (N) = N_Expanded_Name
           and then Comes_From_Source (N)
         then
            Error_Msg_N
              ("discriminant must appear alone as a direct name", N);
         end if;

         return;

      --  Otherwise, context is an expression. It should not be within (i.e. a
      --  subexpression of) a constraint for a component.

      else
         D := PN;
         P := Parent (PN);
         while not Nkind_In (P, N_Component_Declaration,
                                N_Subtype_Indication,
                                N_Entry_Declaration)
         loop
            D := P;
            P := Parent (P);
            exit when No (P);
         end loop;

         --  If the discriminant is used in an expression that is a bound of a
         --  scalar type, an Itype is created and the bounds are attached to
         --  its range, not to the original subtype indication. Such use is of
         --  course a double fault.

         if (Nkind (P) = N_Subtype_Indication
              and then Nkind_In (Parent (P), N_Component_Definition,
                                             N_Derived_Type_Definition)
              and then D = Constraint (P))

           --  The constraint itself may be given by a subtype indication,
           --  rather than by a more common discrete range.

           or else (Nkind (P) = N_Subtype_Indication
                      and then
                    Nkind (Parent (P)) = N_Index_Or_Discriminant_Constraint)
           or else Nkind (P) = N_Entry_Declaration
           or else Nkind (D) = N_Defining_Identifier
         then
            Error_Msg_N
              ("discriminant in constraint must appear alone",  N);
         end if;
      end if;
   end Check_Discriminant_Use;

   --------------------------------
   -- Check_For_Visible_Operator --
   --------------------------------

   procedure Check_For_Visible_Operator (N : Node_Id; T : Entity_Id) is
   begin
      if Is_Invisible_Operator (N, T) then
         Error_Msg_NE -- CODEFIX
           ("operator for} is not directly visible!", N, First_Subtype (T));
         Error_Msg_N -- CODEFIX
           ("use clause would make operation legal!", N);
      end if;
   end Check_For_Visible_Operator;

   ----------------------------------
   --  Check_Fully_Declared_Prefix --
   ----------------------------------

   procedure Check_Fully_Declared_Prefix
     (Typ  : Entity_Id;
      Pref : Node_Id)
   is
   begin
      --  Check that the designated type of the prefix of a dereference is
      --  not an incomplete type. This cannot be done unconditionally, because
      --  dereferences of private types are legal in default expressions. This
      --  case is taken care of in Check_Fully_Declared, called below. There
      --  are also 2005 cases where it is legal for the prefix to be unfrozen.

      --  This consideration also applies to similar checks for allocators,
      --  qualified expressions, and type conversions.

      --  An additional exception concerns other per-object expressions that
      --  are not directly related to component declarations, in particular
      --  representation pragmas for tasks. These will be per-object
      --  expressions if they depend on discriminants or some global entity.
      --  If the task has access discriminants, the designated type may be
      --  incomplete at the point the expression is resolved. This resolution
      --  takes place within the body of the initialization procedure, where
      --  the discriminant is replaced by its discriminal.

      if Is_Entity_Name (Pref)
        and then Ekind (Entity (Pref)) = E_In_Parameter
      then
         null;

      --  Ada 2005 (AI-326): Tagged incomplete types allowed. The wrong usages
      --  are handled by Analyze_Access_Attribute, Analyze_Assignment,
      --  Analyze_Object_Renaming, and Freeze_Entity.

      elsif Ada_Version >= Ada_2005
        and then Is_Entity_Name (Pref)
        and then Is_Access_Type (Etype (Pref))
        and then Ekind (Directly_Designated_Type (Etype (Pref))) =
                                                       E_Incomplete_Type
        and then Is_Tagged_Type (Directly_Designated_Type (Etype (Pref)))
      then
         null;
      else
         Check_Fully_Declared (Typ, Parent (Pref));
      end if;
   end Check_Fully_Declared_Prefix;

   ------------------------------
   -- Check_Infinite_Recursion --
   ------------------------------

   function Check_Infinite_Recursion (Call : Node_Id) return Boolean is
      function Enclosing_Declaration_Or_Statement (N : Node_Id) return Node_Id;
      --  Return the nearest enclosing declaration or statement that houses
      --  arbitrary node N.

      function Invoked_With_Different_Arguments (N : Node_Id) return Boolean;
      --  Determine whether call N invokes the related enclosing subprogram
      --  with actuals that differ from the subprogram's formals.

      function Is_Conditional_Statement (N : Node_Id) return Boolean;
      --  Determine whether arbitrary node N denotes a conditional construct

      function Is_Control_Flow_Statement (N : Node_Id) return Boolean;
      --  Determine whether arbitrary node N denotes a control flow statement
      --  or a construct that may contains such a statement.

      function Is_Immediately_Within_Body (N : Node_Id) return Boolean;
      --  Determine whether arbitrary node N appears immediately within the
      --  statements of an entry or subprogram body.

      function Is_Raise_Idiom (N : Node_Id) return Boolean;
      --  Determine whether arbitrary node N appears immediately within the
      --  body of an entry or subprogram, and is preceded by a single raise
      --  statement.

      function Is_Raise_Statement (N : Node_Id) return Boolean;
      --  Determine whether arbitrary node N denotes a raise statement

      function Is_Sole_Statement (N : Node_Id) return Boolean;
      --  Determine whether arbitrary node N is the sole source statement in
      --  the body of the enclosing subprogram.

      function Preceded_By_Control_Flow_Statement (N : Node_Id) return Boolean;
      --  Determine whether arbitrary node N is preceded by a control flow
      --  statement.

      function Within_Conditional_Statement (N : Node_Id) return Boolean;
      --  Determine whether arbitrary node N appears within a conditional
      --  construct.

      ----------------------------------------
      -- Enclosing_Declaration_Or_Statement --
      ----------------------------------------

      function Enclosing_Declaration_Or_Statement
        (N : Node_Id) return Node_Id
      is
         Par : Node_Id;

      begin
         Par := N;
         while Present (Par) loop
            if Is_Declaration (Par) or else Is_Statement (Par) then
               return Par;

            --  Prevent the search from going too far

            elsif Is_Body_Or_Package_Declaration (Par) then
               exit;
            end if;

            Par := Parent (Par);
         end loop;

         return N;
      end Enclosing_Declaration_Or_Statement;

      --------------------------------------
      -- Invoked_With_Different_Arguments --
      --------------------------------------

      function Invoked_With_Different_Arguments (N : Node_Id) return Boolean is
         Subp : constant Entity_Id := Entity (Name (N));

         Actual : Node_Id;
         Formal : Entity_Id;

      begin
         --  Determine whether the formals of the invoked subprogram are not
         --  used as actuals in the call.

         Actual := First_Actual (Call);
         Formal := First_Formal (Subp);
         while Present (Actual) and then Present (Formal) loop

            --  The current actual does not match the current formal

            if not (Is_Entity_Name (Actual)
                     and then Entity (Actual) = Formal)
            then
               return True;
            end if;

            Next_Actual (Actual);
            Next_Formal (Formal);
         end loop;

         return False;
      end Invoked_With_Different_Arguments;

      ------------------------------
      -- Is_Conditional_Statement --
      ------------------------------

      function Is_Conditional_Statement (N : Node_Id) return Boolean is
      begin
         return
           Nkind_In (N, N_And_Then,
                        N_Case_Expression,
                        N_Case_Statement,
                        N_If_Expression,
                        N_If_Statement,
                        N_Or_Else);
      end Is_Conditional_Statement;

      -------------------------------
      -- Is_Control_Flow_Statement --
      -------------------------------

      function Is_Control_Flow_Statement (N : Node_Id) return Boolean is
      begin
         --  It is assumed that all statements may affect the control flow in
         --  some way. A raise statement may be expanded into a non-statement
         --  node.

         return Is_Statement (N) or else Is_Raise_Statement (N);
      end Is_Control_Flow_Statement;

      --------------------------------
      -- Is_Immediately_Within_Body --
      --------------------------------

      function Is_Immediately_Within_Body (N : Node_Id) return Boolean is
         HSS : constant Node_Id := Parent (N);

      begin
         return
           Nkind (HSS) = N_Handled_Sequence_Of_Statements
             and then Nkind_In (Parent (HSS), N_Entry_Body, N_Subprogram_Body)
             and then Is_List_Member (N)
             and then List_Containing (N) = Statements (HSS);
      end Is_Immediately_Within_Body;

      --------------------
      -- Is_Raise_Idiom --
      --------------------

      function Is_Raise_Idiom (N : Node_Id) return Boolean is
         Raise_Stmt : Node_Id;
         Stmt       : Node_Id;

      begin
         if Is_Immediately_Within_Body (N) then

            --  Assume that no raise statement has been seen yet

            Raise_Stmt := Empty;

            --  Examine the statements preceding the input node, skipping
            --  internally-generated constructs.

            Stmt := Prev (N);
            while Present (Stmt) loop

               --  Multiple raise statements violate the idiom

               if Is_Raise_Statement (Stmt) then
                  if Present (Raise_Stmt) then
                     return False;
                  end if;

                  Raise_Stmt := Stmt;

               elsif Comes_From_Source (Stmt) then
                  exit;
               end if;

               Stmt := Prev (Stmt);
            end loop;

            --  At this point the node must be preceded by a raise statement,
            --  and the raise statement has to be the sole statement within
            --  the enclosing entry or subprogram body.

            return
              Present (Raise_Stmt) and then Is_Sole_Statement (Raise_Stmt);
         end if;

         return False;
      end Is_Raise_Idiom;

      ------------------------
      -- Is_Raise_Statement --
      ------------------------

      function Is_Raise_Statement (N : Node_Id) return Boolean is
      begin
         --  A raise statement may be transfomed into a Raise_xxx_Error node

         return
           Nkind (N) = N_Raise_Statement
             or else Nkind (N) in N_Raise_xxx_Error;
      end Is_Raise_Statement;

      -----------------------
      -- Is_Sole_Statement --
      -----------------------

      function Is_Sole_Statement (N : Node_Id) return Boolean is
         Stmt : Node_Id;

      begin
         --  The input node appears within the statements of an entry or
         --  subprogram body. Examine the statements preceding the node.

         if Is_Immediately_Within_Body (N) then
            Stmt := Prev (N);

            while Present (Stmt) loop

               --  The statement is preceded by another statement or a source
               --  construct. This indicates that the node does not appear by
               --  itself.

               if Is_Control_Flow_Statement (Stmt)
                 or else Comes_From_Source (Stmt)
               then
                  return False;
               end if;

               Stmt := Prev (Stmt);
            end loop;

            return True;
         end if;

         --  The input node is within a construct nested inside the entry or
         --  subprogram body.

         return False;
      end Is_Sole_Statement;

      ----------------------------------------
      -- Preceded_By_Control_Flow_Statement --
      ----------------------------------------

      function Preceded_By_Control_Flow_Statement
        (N : Node_Id) return Boolean
      is
         Stmt : Node_Id;

      begin
         if Is_List_Member (N) then
            Stmt := Prev (N);

            --  Examine the statements preceding the input node

            while Present (Stmt) loop
               if Is_Control_Flow_Statement (Stmt) then
                  return True;
               end if;

               Stmt := Prev (Stmt);
            end loop;

            return False;
         end if;

         --  Assume that the node is part of some control flow statement

         return True;
      end Preceded_By_Control_Flow_Statement;

      ----------------------------------
      -- Within_Conditional_Statement --
      ----------------------------------

      function Within_Conditional_Statement (N : Node_Id) return Boolean is
         Stmt : Node_Id;

      begin
         Stmt := Parent (N);
         while Present (Stmt) loop
            if Is_Conditional_Statement (Stmt) then
               return True;

            --  Prevent the search from going too far

            elsif Is_Body_Or_Package_Declaration (Stmt) then
               exit;
            end if;

            Stmt := Parent (Stmt);
         end loop;

         return False;
      end Within_Conditional_Statement;

      --  Local variables

      Call_Context : constant Node_Id :=
                       Enclosing_Declaration_Or_Statement (Call);

   --  Start of processing for Check_Infinite_Recursion

   begin
      --  The call is assumed to be safe when the enclosing subprogram is
      --  invoked with actuals other than its formals.
      --
      --    procedure Proc (F1 : ...; F2 : ...; ...; FN : ...) is
      --    begin
      --       ...
      --       Proc (A1, A2, ..., AN);
      --       ...
      --    end Proc;

      if Invoked_With_Different_Arguments (Call) then
         return False;

      --  The call is assumed to be safe when the invocation of the enclosing
      --  subprogram depends on a conditional statement.
      --
      --    procedure Proc (F1 : ...; F2 : ...; ...; FN : ...) is
      --    begin
      --       ...
      --       if Some_Condition then
      --          Proc (F1, F2, ..., FN);
      --       end if;
      --       ...
      --    end Proc;

      elsif Within_Conditional_Statement (Call) then
         return False;

      --  The context of the call is assumed to be safe when the invocation of
      --  the enclosing subprogram is preceded by some control flow statement.
      --
      --    procedure Proc (F1 : ...; F2 : ...; ...; FN : ...) is
      --    begin
      --       ...
      --       if Some_Condition then
      --          ...
      --       end if;
      --       ...
      --       Proc (F1, F2, ..., FN);
      --       ...
      --    end Proc;

      elsif Preceded_By_Control_Flow_Statement (Call_Context) then
         return False;

      --  Detect an idiom where the context of the call is preceded by a single
      --  raise statement.
      --
      --    procedure Proc (F1 : ...; F2 : ...; ...; FN : ...) is
      --    begin
      --       raise ...;
      --       Proc (F1, F2, ..., FN);
      --    end Proc;

      elsif Is_Raise_Idiom (Call_Context) then
         return False;
      end if;

      --  At this point it is certain that infinite recursion will take place
      --  as long as the call is executed. Detect a case where the context of
      --  the call is the sole source statement within the subprogram body.
      --
      --    procedure Proc (F1 : ...; F2 : ...; ...; FN : ...) is
      --    begin
      --       Proc (F1, F2, ..., FN);
      --    end Proc;
      --
      --  Install an explicit raise to prevent the infinite recursion.

      if Is_Sole_Statement (Call_Context) then
         Error_Msg_Warn := SPARK_Mode /= On;
         Error_Msg_N ("!infinite recursion<<", Call);
         Error_Msg_N ("\!Storage_Error [<<", Call);

         Insert_Action (Call,
           Make_Raise_Storage_Error (Sloc (Call),
             Reason => SE_Infinite_Recursion));

      --  Otherwise infinite recursion could take place, considering other flow
      --  control constructs such as gotos, exit statements, etc.

      else
         Error_Msg_Warn := SPARK_Mode /= On;
         Error_Msg_N ("!possible infinite recursion<<", Call);
         Error_Msg_N ("\!??Storage_Error ]<<", Call);
      end if;

      return True;
   end Check_Infinite_Recursion;

   ---------------------------------------
   -- Check_No_Direct_Boolean_Operators --
   ---------------------------------------

   procedure Check_No_Direct_Boolean_Operators (N : Node_Id) is
   begin
      if Scope (Entity (N)) = Standard_Standard
        and then Root_Type (Etype (Left_Opnd (N))) = Standard_Boolean
      then
         --  Restriction only applies to original source code

         if Comes_From_Source (N) then
            Check_Restriction (No_Direct_Boolean_Operators, N);
         end if;
      end if;

      --  Do style check (but skip if in instance, error is on template)

      if Style_Check then
         if not In_Instance then
            Check_Boolean_Operator (N);
         end if;
      end if;
   end Check_No_Direct_Boolean_Operators;

   ------------------------------
   -- Check_Parameterless_Call --
   ------------------------------

   procedure Check_Parameterless_Call (N : Node_Id) is
      Nam : Node_Id;

      function Prefix_Is_Access_Subp return Boolean;
      --  If the prefix is of an access_to_subprogram type, the node must be
      --  rewritten as a call. Ditto if the prefix is overloaded and all its
      --  interpretations are access to subprograms.

      ---------------------------
      -- Prefix_Is_Access_Subp --
      ---------------------------

      function Prefix_Is_Access_Subp return Boolean is
         I   : Interp_Index;
         It  : Interp;

      begin
         --  If the context is an attribute reference that can apply to
         --  functions, this is never a parameterless call (RM 4.1.4(6)).

         if Nkind (Parent (N)) = N_Attribute_Reference
            and then Nam_In (Attribute_Name (Parent (N)), Name_Address,
                                                          Name_Code_Address,
                                                          Name_Access)
         then
            return False;
         end if;

         if not Is_Overloaded (N) then
            return
              Ekind (Etype (N)) = E_Subprogram_Type
                and then Base_Type (Etype (Etype (N))) /= Standard_Void_Type;
         else
            Get_First_Interp (N, I, It);
            while Present (It.Typ) loop
               if Ekind (It.Typ) /= E_Subprogram_Type
                 or else Base_Type (Etype (It.Typ)) = Standard_Void_Type
               then
                  return False;
               end if;

               Get_Next_Interp (I, It);
            end loop;

            return True;
         end if;
      end Prefix_Is_Access_Subp;

   --  Start of processing for Check_Parameterless_Call

   begin
      --  Defend against junk stuff if errors already detected

      if Total_Errors_Detected /= 0 then
         if Nkind (N) in N_Has_Etype and then Etype (N) = Any_Type then
            return;
         elsif Nkind (N) in N_Has_Chars
           and then not Is_Valid_Name (Chars (N))
         then
            return;
         end if;

         Require_Entity (N);
      end if;

      --  If the context expects a value, and the name is a procedure, this is
      --  most likely a missing 'Access. Don't try to resolve the parameterless
      --  call, error will be caught when the outer call is analyzed.

      if Is_Entity_Name (N)
        and then Ekind (Entity (N)) = E_Procedure
        and then not Is_Overloaded (N)
        and then
         Nkind_In (Parent (N), N_Parameter_Association,
                               N_Function_Call,
                               N_Procedure_Call_Statement)
      then
         return;
      end if;

      --  Rewrite as call if overloadable entity that is (or could be, in the
      --  overloaded case) a function call. If we know for sure that the entity
      --  is an enumeration literal, we do not rewrite it.

      --  If the entity is the name of an operator, it cannot be a call because
      --  operators cannot have default parameters. In this case, this must be
      --  a string whose contents coincide with an operator name. Set the kind
      --  of the node appropriately.

      if (Is_Entity_Name (N)
            and then Nkind (N) /= N_Operator_Symbol
            and then Is_Overloadable (Entity (N))
            and then (Ekind (Entity (N)) /= E_Enumeration_Literal
                       or else Is_Overloaded (N)))

      --  Rewrite as call if it is an explicit dereference of an expression of
      --  a subprogram access type, and the subprogram type is not that of a
      --  procedure or entry.

      or else
        (Nkind (N) = N_Explicit_Dereference and then Prefix_Is_Access_Subp)

      --  Rewrite as call if it is a selected component which is a function,
      --  this is the case of a call to a protected function (which may be
      --  overloaded with other protected operations).

      or else
        (Nkind (N) = N_Selected_Component
          and then (Ekind (Entity (Selector_Name (N))) = E_Function
                     or else
                       (Ekind_In (Entity (Selector_Name (N)), E_Entry,
                                                              E_Procedure)
                         and then Is_Overloaded (Selector_Name (N)))))

      --  If one of the above three conditions is met, rewrite as call. Apply
      --  the rewriting only once.

      then
         if Nkind (Parent (N)) /= N_Function_Call
           or else N /= Name (Parent (N))
         then

            --  This may be a prefixed call that was not fully analyzed, e.g.
            --  an actual in an instance.

            if Ada_Version >= Ada_2005
              and then Nkind (N) = N_Selected_Component
              and then Is_Dispatching_Operation (Entity (Selector_Name (N)))
            then
               Analyze_Selected_Component (N);

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

            --  The node is the name of the parameterless call. Preserve its
            --  descendants, which may be complex expressions.

            Nam := Relocate_Node (N);

            --  If overloaded, overload set belongs to new copy

            Save_Interps (N, Nam);

            --  Change node to parameterless function call (note that the
            --  Parameter_Associations associations field is left set to Empty,
            --  its normal default value since there are no parameters)

            Change_Node (N, N_Function_Call);
            Set_Name (N, Nam);
            Set_Sloc (N, Sloc (Nam));
            Analyze_Call (N);
         end if;

      elsif Nkind (N) = N_Parameter_Association then
         Check_Parameterless_Call (Explicit_Actual_Parameter (N));

      elsif Nkind (N) = N_Operator_Symbol then
         Change_Operator_Symbol_To_String_Literal (N);
         Set_Is_Overloaded (N, False);
         Set_Etype (N, Any_String);
      end if;
   end Check_Parameterless_Call;

   --------------------------------
   -- Is_Atomic_Ref_With_Address --
   --------------------------------

   function Is_Atomic_Ref_With_Address (N : Node_Id) return Boolean is
      Pref : constant Node_Id := Prefix (N);

   begin
      if not Is_Entity_Name (Pref) then
         return False;

      else
         declare
            Pent : constant Entity_Id := Entity (Pref);
            Ptyp : constant Entity_Id := Etype (Pent);
         begin
            return not Is_Access_Type (Ptyp)
              and then (Is_Atomic (Ptyp) or else Is_Atomic (Pent))
              and then Present (Address_Clause (Pent));
         end;
      end if;
   end Is_Atomic_Ref_With_Address;

   -----------------------------
   -- Is_Definite_Access_Type --
   -----------------------------

   function Is_Definite_Access_Type (E : Entity_Id) return Boolean is
      Btyp : constant Entity_Id := Base_Type (E);
   begin
      return Ekind (Btyp) = E_Access_Type
        or else (Ekind (Btyp) = E_Access_Subprogram_Type
                  and then Comes_From_Source (Btyp));
   end Is_Definite_Access_Type;

   ----------------------
   -- Is_Predefined_Op --
   ----------------------

   function Is_Predefined_Op (Nam : Entity_Id) return Boolean is
   begin
      --  Predefined operators are intrinsic subprograms

      if not Is_Intrinsic_Subprogram (Nam) then
         return False;
      end if;

      --  A call to a back-end builtin is never a predefined operator

      if Is_Imported (Nam) and then Present (Interface_Name (Nam)) then
         return False;
      end if;

      return not Is_Generic_Instance (Nam)
        and then Chars (Nam) in Any_Operator_Name
        and then (No (Alias (Nam)) or else Is_Predefined_Op (Alias (Nam)));
   end Is_Predefined_Op;

   -----------------------------
   -- Make_Call_Into_Operator --
   -----------------------------

   procedure Make_Call_Into_Operator
     (N     : Node_Id;
      Typ   : Entity_Id;
      Op_Id : Entity_Id)
   is
      Op_Name   : constant Name_Id := Chars (Op_Id);
      Act1      : Node_Id := First_Actual (N);
      Act2      : Node_Id := Next_Actual (Act1);
      Error     : Boolean := False;
      Func      : constant Entity_Id := Entity (Name (N));
      Is_Binary : constant Boolean   := Present (Act2);
      Op_Node   : Node_Id;
      Opnd_Type : Entity_Id := Empty;
      Orig_Type : Entity_Id := Empty;
      Pack      : Entity_Id;

      type Kind_Test is access function (E : Entity_Id) return Boolean;

      function Operand_Type_In_Scope (S : Entity_Id) return Boolean;
      --  If the operand is not universal, and the operator is given by an
      --  expanded name, verify that the operand has an interpretation with a
      --  type defined in the given scope of the operator.

      function Type_In_P (Test : Kind_Test) return Entity_Id;
      --  Find a type of the given class in package Pack that contains the
      --  operator.

      ---------------------------
      -- Operand_Type_In_Scope --
      ---------------------------

      function Operand_Type_In_Scope (S : Entity_Id) return Boolean is
         Nod : constant Node_Id := Right_Opnd (Op_Node);
         I   : Interp_Index;
         It  : Interp;

      begin
         if not Is_Overloaded (Nod) then
            return Scope (Base_Type (Etype (Nod))) = S;

         else
            Get_First_Interp (Nod, I, It);
            while Present (It.Typ) loop
               if Scope (Base_Type (It.Typ)) = S then
                  return True;
               end if;

               Get_Next_Interp (I, It);
            end loop;

            return False;
         end if;
      end Operand_Type_In_Scope;

      ---------------
      -- Type_In_P --
      ---------------

      function Type_In_P (Test : Kind_Test) return Entity_Id is
         E : Entity_Id;

         function In_Decl return Boolean;
         --  Verify that node is not part of the type declaration for the
         --  candidate type, which would otherwise be invisible.

         -------------
         -- In_Decl --
         -------------

         function In_Decl return Boolean is
            Decl_Node : constant Node_Id := Parent (E);
            N2        : Node_Id;

         begin
            N2 := N;

            if Etype (E) = Any_Type then
               return True;

            elsif No (Decl_Node) then
               return False;

            else
               while Present (N2)
                 and then Nkind (N2) /= N_Compilation_Unit
               loop
                  if N2 = Decl_Node then
                     return True;
                  else
                     N2 := Parent (N2);
                  end if;
               end loop;

               return False;
            end if;
         end In_Decl;

      --  Start of processing for Type_In_P

      begin
         --  If the context type is declared in the prefix package, this is the
         --  desired base type.

         if Scope (Base_Type (Typ)) = Pack and then Test (Typ) then
            return Base_Type (Typ);

         else
            E := First_Entity (Pack);
            while Present (E) loop
               if Test (E) and then not In_Decl then
                  return E;
               end if;

               Next_Entity (E);
            end loop;

            return Empty;
         end if;
      end Type_In_P;

   --  Start of processing for Make_Call_Into_Operator

   begin
      Op_Node := New_Node (Operator_Kind (Op_Name, Is_Binary), Sloc (N));

      --  Ensure that the corresponding operator has the same parent as the
      --  original call. This guarantees that parent traversals performed by
      --  the ABE mechanism succeed.

      Set_Parent (Op_Node, Parent (N));

      --  Binary operator

      if Is_Binary then
         Set_Left_Opnd  (Op_Node, Relocate_Node (Act1));
         Set_Right_Opnd (Op_Node, Relocate_Node (Act2));
         Save_Interps (Act1, Left_Opnd  (Op_Node));
         Save_Interps (Act2, Right_Opnd (Op_Node));
         Act1 := Left_Opnd (Op_Node);
         Act2 := Right_Opnd (Op_Node);

      --  Unary operator

      else
         Set_Right_Opnd (Op_Node, Relocate_Node (Act1));
         Save_Interps (Act1, Right_Opnd (Op_Node));
         Act1 := Right_Opnd (Op_Node);
      end if;

      --  If the operator is denoted by an expanded name, and the prefix is
      --  not Standard, but the operator is a predefined one whose scope is
      --  Standard, then this is an implicit_operator, inserted as an
      --  interpretation by the procedure of the same name. This procedure
      --  overestimates the presence of implicit operators, because it does
      --  not examine the type of the operands. Verify now that the operand
      --  type appears in the given scope. If right operand is universal,
      --  check the other operand. In the case of concatenation, either
      --  argument can be the component type, so check the type of the result.
      --  If both arguments are literals, look for a type of the right kind
      --  defined in the given scope. This elaborate nonsense is brought to
      --  you courtesy of b33302a. The type itself must be frozen, so we must
      --  find the type of the proper class in the given scope.

      --  A final wrinkle is the multiplication operator for fixed point types,
      --  which is defined in Standard only, and not in the scope of the
      --  fixed point type itself.

      if Nkind (Name (N)) = N_Expanded_Name then
         Pack := Entity (Prefix (Name (N)));

         --  If this is a package renaming, get renamed entity, which will be
         --  the scope of the operands if operaton is type-correct.

         if Present (Renamed_Entity (Pack)) then
            Pack := Renamed_Entity (Pack);
         end if;

         --  If the entity being called is defined in the given package, it is
         --  a renaming of a predefined operator, and known to be legal.

         if Scope (Entity (Name (N))) = Pack
            and then Pack /= Standard_Standard
         then
            null;

         --  Visibility does not need to be checked in an instance: if the
         --  operator was not visible in the generic it has been diagnosed
         --  already, else there is an implicit copy of it in the instance.

         elsif In_Instance then
            null;

         elsif Nam_In (Op_Name, Name_Op_Multiply, Name_Op_Divide)
           and then Is_Fixed_Point_Type (Etype (Left_Opnd  (Op_Node)))
           and then Is_Fixed_Point_Type (Etype (Right_Opnd (Op_Node)))
         then
            if Pack /= Standard_Standard then
               Error := True;
            end if;

         --  Ada 2005 AI-420: Predefined equality on Universal_Access is
         --  available.

         elsif Ada_Version >= Ada_2005
           and then Nam_In (Op_Name, Name_Op_Eq, Name_Op_Ne)
           and then Ekind (Etype (Act1)) = E_Anonymous_Access_Type
         then
            null;

         else
            Opnd_Type := Base_Type (Etype (Right_Opnd (Op_Node)));

            if Op_Name = Name_Op_Concat then
               Opnd_Type := Base_Type (Typ);

            elsif (Scope (Opnd_Type) = Standard_Standard
                    and then Is_Binary)
              or else (Nkind (Right_Opnd (Op_Node)) = N_Attribute_Reference
                        and then Is_Binary
                        and then not Comes_From_Source (Opnd_Type))
            then
               Opnd_Type := Base_Type (Etype (Left_Opnd (Op_Node)));
            end if;

            if Scope (Opnd_Type) = Standard_Standard then

               --  Verify that the scope contains a type that corresponds to
               --  the given literal. Optimize the case where Pack is Standard.

               if Pack /= Standard_Standard then
                  if Opnd_Type = Universal_Integer then
                     Orig_Type := Type_In_P (Is_Integer_Type'Access);

                  elsif Opnd_Type = Universal_Real then
                     Orig_Type := Type_In_P (Is_Real_Type'Access);

                  elsif Opnd_Type = Any_String then
                     Orig_Type := Type_In_P (Is_String_Type'Access);

                  elsif Opnd_Type = Any_Access then
                     Orig_Type := Type_In_P (Is_Definite_Access_Type'Access);

                  elsif Opnd_Type = Any_Composite then
                     Orig_Type := Type_In_P (Is_Composite_Type'Access);

                     if Present (Orig_Type) then
                        if Has_Private_Component (Orig_Type) then
                           Orig_Type := Empty;
                        else
                           Set_Etype (Act1, Orig_Type);

                           if Is_Binary then
                              Set_Etype (Act2, Orig_Type);
                           end if;
                        end if;
                     end if;

                  else
                     Orig_Type := Empty;
                  end if;

                  Error := No (Orig_Type);
               end if;

            elsif Ekind (Opnd_Type) = E_Allocator_Type
               and then No (Type_In_P (Is_Definite_Access_Type'Access))
            then
               Error := True;

            --  If the type is defined elsewhere, and the operator is not
            --  defined in the given scope (by a renaming declaration, e.g.)
            --  then this is an error as well. If an extension of System is
            --  present, and the type may be defined there, Pack must be
            --  System itself.

            elsif Scope (Opnd_Type) /= Pack
              and then Scope (Op_Id) /= Pack
              and then (No (System_Aux_Id)
                         or else Scope (Opnd_Type) /= System_Aux_Id
                         or else Pack /= Scope (System_Aux_Id))
            then
               if not Is_Overloaded (Right_Opnd (Op_Node)) then
                  Error := True;
               else
                  Error := not Operand_Type_In_Scope (Pack);
               end if;

            elsif Pack = Standard_Standard
              and then not Operand_Type_In_Scope (Standard_Standard)
            then
               Error := True;
            end if;
         end if;

         if Error then
            Error_Msg_Node_2 := Pack;
            Error_Msg_NE
              ("& not declared in&", N, Selector_Name (Name (N)));
            Set_Etype (N, Any_Type);
            return;

         --  Detect a mismatch between the context type and the result type
         --  in the named package, which is otherwise not detected if the
         --  operands are universal. Check is only needed if source entity is
         --  an operator, not a function that renames an operator.

         elsif Nkind (Parent (N)) /= N_Type_Conversion
           and then Ekind (Entity (Name (N))) = E_Operator
           and then Is_Numeric_Type (Typ)
           and then not Is_Universal_Numeric_Type (Typ)
           and then Scope (Base_Type (Typ)) /= Pack
           and then not In_Instance
         then
            if Is_Fixed_Point_Type (Typ)
              and then Nam_In (Op_Name, Name_Op_Multiply, Name_Op_Divide)
            then
               --  Already checked above

               null;

            --  Operator may be defined in an extension of System

            elsif Present (System_Aux_Id)
              and then Present (Opnd_Type)
              and then Scope (Opnd_Type) = System_Aux_Id
            then
               null;

            else
               --  Could we use Wrong_Type here??? (this would require setting
               --  Etype (N) to the actual type found where Typ was expected).

               Error_Msg_NE ("expect }", N, Typ);
            end if;
         end if;
      end if;

      Set_Chars  (Op_Node, Op_Name);

      if not Is_Private_Type (Etype (N)) then
         Set_Etype (Op_Node, Base_Type (Etype (N)));
      else
         Set_Etype (Op_Node, Etype (N));
      end if;

      --  If this is a call to a function that renames a predefined equality,
      --  the renaming declaration provides a type that must be used to
      --  resolve the operands. This must be done now because resolution of
      --  the equality node will not resolve any remaining ambiguity, and it
      --  assumes that the first operand is not overloaded.

      if Nam_In (Op_Name, Name_Op_Eq, Name_Op_Ne)
        and then Ekind (Func) = E_Function
        and then Is_Overloaded (Act1)
      then
         Resolve (Act1, Base_Type (Etype (First_Formal (Func))));
         Resolve (Act2, Base_Type (Etype (First_Formal (Func))));
      end if;

      Set_Entity (Op_Node, Op_Id);
      Generate_Reference (Op_Id, N, ' ');

      --  Do rewrite setting Comes_From_Source on the result if the original
      --  call came from source. Although it is not strictly the case that the
      --  operator as such comes from the source, logically it corresponds
      --  exactly to the function call in the source, so it should be marked
      --  this way (e.g. to make sure that validity checks work fine).

      declare
         CS : constant Boolean := Comes_From_Source (N);
      begin
         Rewrite (N, Op_Node);
         Set_Comes_From_Source (N, CS);
      end;

      --  If this is an arithmetic operator and the result type is private,
      --  the operands and the result must be wrapped in conversion to
      --  expose the underlying numeric type and expand the proper checks,
      --  e.g. on division.

      if Is_Private_Type (Typ) then
         case Nkind (N) is
            when N_Op_Add
               | N_Op_Divide
               | N_Op_Expon
               | N_Op_Mod
               | N_Op_Multiply
               | N_Op_Rem
               | N_Op_Subtract
            =>
               Resolve_Intrinsic_Operator (N, Typ);

            when N_Op_Abs
               | N_Op_Minus
               | N_Op_Plus
            =>
               Resolve_Intrinsic_Unary_Operator (N, Typ);

            when others =>
               Resolve (N, Typ);
         end case;
      else
         Resolve (N, Typ);
      end if;

      --  If in ASIS_Mode, propagate operand types to original actuals of
      --  function call, which would otherwise not be fully resolved. If
      --  the call has already been constant-folded, nothing to do. We
      --  relocate the operand nodes rather than copy them, to preserve
      --  original_node pointers, given that the operands themselves may
      --  have been rewritten. If the call was itself a rewriting of an
      --  operator node, nothing to do.

      if ASIS_Mode
        and then Nkind (N) in N_Op
        and then Nkind (Original_Node (N)) = N_Function_Call
      then
         declare
            L : Node_Id;
            R : constant Node_Id := Right_Opnd (N);

            Old_First : constant Node_Id :=
                          First (Parameter_Associations (Original_Node (N)));
            Old_Sec   : Node_Id;

         begin
            if Is_Binary then
               L       := Left_Opnd (N);
               Old_Sec := Next (Old_First);

               --  If the original call has named associations, replace the
               --  explicit actual parameter in the association with the proper
               --  resolved operand.

               if Nkind (Old_First) = N_Parameter_Association then
                  if Chars (Selector_Name (Old_First)) =
                     Chars (First_Entity (Op_Id))
                  then
                     Rewrite (Explicit_Actual_Parameter (Old_First),
                       Relocate_Node (L));
                  else
                     Rewrite (Explicit_Actual_Parameter (Old_First),
                       Relocate_Node (R));
                  end if;

               else
                  Rewrite (Old_First, Relocate_Node (L));
               end if;

               if Nkind (Old_Sec) = N_Parameter_Association then
                  if Chars (Selector_Name (Old_Sec)) =
                     Chars (First_Entity (Op_Id))
                  then
                     Rewrite (Explicit_Actual_Parameter (Old_Sec),
                       Relocate_Node (L));
                  else
                     Rewrite (Explicit_Actual_Parameter (Old_Sec),
                       Relocate_Node (R));
                  end if;

               else
                  Rewrite (Old_Sec, Relocate_Node (R));
               end if;

            else
               if Nkind (Old_First) = N_Parameter_Association then
                  Rewrite (Explicit_Actual_Parameter (Old_First),
                    Relocate_Node (R));
               else
                  Rewrite (Old_First, Relocate_Node (R));
               end if;
            end if;
         end;

         Set_Parent (Original_Node (N), Parent (N));
      end if;
   end Make_Call_Into_Operator;

   -------------------
   -- Operator_Kind --
   -------------------

   function Operator_Kind
     (Op_Name   : Name_Id;
      Is_Binary : Boolean) return Node_Kind
   is
      Kind : Node_Kind;

   begin
      --  Use CASE statement or array???

      if Is_Binary then
         if    Op_Name = Name_Op_And      then
            Kind := N_Op_And;
         elsif Op_Name = Name_Op_Or       then
            Kind := N_Op_Or;
         elsif Op_Name = Name_Op_Xor      then
            Kind := N_Op_Xor;
         elsif Op_Name = Name_Op_Eq       then
            Kind := N_Op_Eq;
         elsif Op_Name = Name_Op_Ne       then
            Kind := N_Op_Ne;
         elsif Op_Name = Name_Op_Lt       then
            Kind := N_Op_Lt;
         elsif Op_Name = Name_Op_Le       then
            Kind := N_Op_Le;
         elsif Op_Name = Name_Op_Gt       then
            Kind := N_Op_Gt;
         elsif Op_Name = Name_Op_Ge       then
            Kind := N_Op_Ge;
         elsif Op_Name = Name_Op_Add      then
            Kind := N_Op_Add;
         elsif Op_Name = Name_Op_Subtract then
            Kind := N_Op_Subtract;
         elsif Op_Name = Name_Op_Concat   then
            Kind := N_Op_Concat;
         elsif Op_Name = Name_Op_Multiply then
            Kind := N_Op_Multiply;
         elsif Op_Name = Name_Op_Divide   then
            Kind := N_Op_Divide;
         elsif Op_Name = Name_Op_Mod      then
            Kind := N_Op_Mod;
         elsif Op_Name = Name_Op_Rem      then
            Kind := N_Op_Rem;
         elsif Op_Name = Name_Op_Expon    then
            Kind := N_Op_Expon;
         else
            raise Program_Error;
         end if;

      --  Unary operators

      else
         if    Op_Name = Name_Op_Add      then
            Kind := N_Op_Plus;
         elsif Op_Name = Name_Op_Subtract then
            Kind := N_Op_Minus;
         elsif Op_Name = Name_Op_Abs      then
            Kind := N_Op_Abs;
         elsif Op_Name = Name_Op_Not      then
            Kind := N_Op_Not;
         else
            raise Program_Error;
         end if;
      end if;

      return Kind;
   end Operator_Kind;

   ----------------------------
   -- Preanalyze_And_Resolve --
   ----------------------------

   procedure Preanalyze_And_Resolve
     (N             : Node_Id;
      T             : Entity_Id;
      With_Freezing : Boolean)
   is
      Save_Full_Analysis     : constant Boolean := Full_Analysis;
      Save_Must_Not_Freeze   : constant Boolean := Must_Not_Freeze (N);
      Save_Preanalysis_Count : constant Nat :=
                                 Inside_Preanalysis_Without_Freezing;
   begin
      pragma Assert (Nkind (N) in N_Subexpr);

      if not With_Freezing then
         Set_Must_Not_Freeze (N);
         Inside_Preanalysis_Without_Freezing :=
           Inside_Preanalysis_Without_Freezing + 1;
      end if;

      Full_Analysis := False;
      Expander_Mode_Save_And_Set (False);

      --  Normally, we suppress all checks for this preanalysis. There is no
      --  point in processing them now, since they will be applied properly
      --  and in the proper location when the default expressions reanalyzed
      --  and reexpanded later on. We will also have more information at that
      --  point for possible suppression of individual checks.

      --  However, in SPARK mode, most expansion is suppressed, and this
      --  later reanalysis and reexpansion may not occur. SPARK mode does
      --  require the setting of checking flags for proof purposes, so we
      --  do the SPARK preanalysis without suppressing checks.

      --  This special handling for SPARK mode is required for example in the
      --  case of Ada 2012 constructs such as quantified expressions, which are
      --  expanded in two separate steps.

      if GNATprove_Mode then
         Analyze_And_Resolve (N, T);
      else
         Analyze_And_Resolve (N, T, Suppress => All_Checks);
      end if;

      Expander_Mode_Restore;
      Full_Analysis := Save_Full_Analysis;
      Set_Must_Not_Freeze (N, Save_Must_Not_Freeze);

      if not With_Freezing then
         Inside_Preanalysis_Without_Freezing :=
           Inside_Preanalysis_Without_Freezing - 1;
      end if;

      pragma Assert
        (Inside_Preanalysis_Without_Freezing = Save_Preanalysis_Count);
   end Preanalyze_And_Resolve;

   ----------------------------
   -- Preanalyze_And_Resolve --
   ----------------------------

   procedure Preanalyze_And_Resolve (N : Node_Id; T : Entity_Id) is
   begin
      Preanalyze_And_Resolve (N, T, With_Freezing => False);
   end Preanalyze_And_Resolve;

   --  Version without context type

   procedure Preanalyze_And_Resolve (N : Node_Id) is
      Save_Full_Analysis : constant Boolean := Full_Analysis;

   begin
      Full_Analysis := False;
      Expander_Mode_Save_And_Set (False);

      Analyze (N);
      Resolve (N, Etype (N), Suppress => All_Checks);

      Expander_Mode_Restore;
      Full_Analysis := Save_Full_Analysis;
   end Preanalyze_And_Resolve;

   ------------------------------------------
   -- Preanalyze_With_Freezing_And_Resolve --
   ------------------------------------------

   procedure Preanalyze_With_Freezing_And_Resolve
     (N : Node_Id;
      T : Entity_Id)
   is
   begin
      Preanalyze_And_Resolve (N, T, With_Freezing => True);
   end Preanalyze_With_Freezing_And_Resolve;

   ----------------------------------
   -- Replace_Actual_Discriminants --
   ----------------------------------

   procedure Replace_Actual_Discriminants (N : Node_Id; Default : Node_Id) is
      Loc : constant Source_Ptr := Sloc (N);
      Tsk : Node_Id := Empty;

      function Process_Discr (Nod : Node_Id) return Traverse_Result;
      --  Comment needed???

      -------------------
      -- Process_Discr --
      -------------------

      function Process_Discr (Nod : Node_Id) return Traverse_Result is
         Ent : Entity_Id;

      begin
         if Nkind (Nod) = N_Identifier then
            Ent := Entity (Nod);

            if Present (Ent)
              and then Ekind (Ent) = E_Discriminant
            then
               Rewrite (Nod,
                 Make_Selected_Component (Loc,
                   Prefix        => New_Copy_Tree (Tsk, New_Sloc => Loc),
                   Selector_Name => Make_Identifier (Loc, Chars (Ent))));

               Set_Etype (Nod, Etype (Ent));
            end if;

         end if;

         return OK;
      end Process_Discr;

      procedure Replace_Discrs is new Traverse_Proc (Process_Discr);

   --  Start of processing for Replace_Actual_Discriminants

   begin
      if Expander_Active then
         null;

      --  Allow the replacement of concurrent discriminants in GNATprove even
      --  though this is a light expansion activity. Note that generic units
      --  are not modified.

      elsif GNATprove_Mode and not Inside_A_Generic then
         null;

      else
         return;
      end if;

      if Nkind (Name (N)) = N_Selected_Component then
         Tsk := Prefix (Name (N));

      elsif Nkind (Name (N)) = N_Indexed_Component then
         Tsk := Prefix (Prefix (Name (N)));
      end if;

      if Present (Tsk) then
         Replace_Discrs (Default);
      end if;
   end Replace_Actual_Discriminants;

   -------------
   -- Resolve --
   -------------

   procedure Resolve (N : Node_Id; Typ : Entity_Id) is
      Ambiguous : Boolean   := False;
      Ctx_Type  : Entity_Id := Typ;
      Expr_Type : Entity_Id := Empty; -- prevent junk warning
      Err_Type  : Entity_Id := Empty;
      Found     : Boolean   := False;
      From_Lib  : Boolean;
      I         : Interp_Index;
      I1        : Interp_Index := 0;  -- prevent junk warning
      It        : Interp;
      It1       : Interp;
      Seen      : Entity_Id := Empty; -- prevent junk warning

      function Comes_From_Predefined_Lib_Unit (Nod : Node_Id) return Boolean;
      --  Determine whether a node comes from a predefined library unit or
      --  Standard.

      procedure Patch_Up_Value (N : Node_Id; Typ : Entity_Id);
      --  Try and fix up a literal so that it matches its expected type. New
      --  literals are manufactured if necessary to avoid cascaded errors.

      procedure Report_Ambiguous_Argument;
      --  Additional diagnostics when an ambiguous call has an ambiguous
      --  argument (typically a controlling actual).

      procedure Resolution_Failed;
      --  Called when attempt at resolving current expression fails

      ------------------------------------
      -- Comes_From_Predefined_Lib_Unit --
      -------------------------------------

      function Comes_From_Predefined_Lib_Unit (Nod : Node_Id) return Boolean is
      begin
         return
           Sloc (Nod) = Standard_Location or else In_Predefined_Unit (Nod);
      end Comes_From_Predefined_Lib_Unit;

      --------------------
      -- Patch_Up_Value --
      --------------------

      procedure Patch_Up_Value (N : Node_Id; Typ : Entity_Id) is
      begin
         if Nkind (N) = N_Integer_Literal and then Is_Real_Type (Typ) then
            Rewrite (N,
              Make_Real_Literal (Sloc (N),
                Realval => UR_From_Uint (Intval (N))));
            Set_Etype (N, Universal_Real);
            Set_Is_Static_Expression (N);

         elsif Nkind (N) = N_Real_Literal and then Is_Integer_Type (Typ) then
            Rewrite (N,
              Make_Integer_Literal (Sloc (N),
                Intval => UR_To_Uint (Realval (N))));
            Set_Etype (N, Universal_Integer);
            Set_Is_Static_Expression (N);

         elsif Nkind (N) = N_String_Literal
                 and then Is_Character_Type (Typ)
         then
            Set_Character_Literal_Name (Char_Code (Character'Pos ('A')));
            Rewrite (N,
              Make_Character_Literal (Sloc (N),
                Chars => Name_Find,
                Char_Literal_Value =>
                  UI_From_Int (Character'Pos ('A'))));
            Set_Etype (N, Any_Character);
            Set_Is_Static_Expression (N);

         elsif Nkind (N) /= N_String_Literal and then Is_String_Type (Typ) then
            Rewrite (N,
              Make_String_Literal (Sloc (N),
                Strval => End_String));

         elsif Nkind (N) = N_Range then
            Patch_Up_Value (Low_Bound (N),  Typ);
            Patch_Up_Value (High_Bound (N), Typ);
         end if;
      end Patch_Up_Value;

      -------------------------------
      -- Report_Ambiguous_Argument --
      -------------------------------

      procedure Report_Ambiguous_Argument is
         Arg : constant Node_Id := First (Parameter_Associations (N));
         I   : Interp_Index;
         It  : Interp;

      begin
         if Nkind (Arg) = N_Function_Call
           and then Is_Entity_Name (Name (Arg))
           and then Is_Overloaded (Name (Arg))
         then
            Error_Msg_NE ("ambiguous call to&", Arg, Name (Arg));

            --  Could use comments on what is going on here???

            Get_First_Interp (Name (Arg), I, It);
            while Present (It.Nam) loop
               Error_Msg_Sloc := Sloc (It.Nam);

               if Nkind (Parent (It.Nam)) = N_Full_Type_Declaration then
                  Error_Msg_N ("interpretation (inherited) #!", Arg);
               else
                  Error_Msg_N ("interpretation #!", Arg);
               end if;

               Get_Next_Interp (I, It);
            end loop;
         end if;
      end Report_Ambiguous_Argument;

      -----------------------
      -- Resolution_Failed --
      -----------------------

      procedure Resolution_Failed is
      begin
         Patch_Up_Value (N, Typ);

         --  Set the type to the desired one to minimize cascaded errors. Note
         --  that this is an approximation and does not work in all cases.

         Set_Etype (N, Typ);

         Debug_A_Exit ("resolving  ", N, " (done, resolution failed)");
         Set_Is_Overloaded (N, False);

         --  The caller will return without calling the expander, so we need
         --  to set the analyzed flag. Note that it is fine to set Analyzed
         --  to True even if we are in the middle of a shallow analysis,
         --  (see the spec of sem for more details) since this is an error
         --  situation anyway, and there is no point in repeating the
         --  analysis later (indeed it won't work to repeat it later, since
         --  we haven't got a clear resolution of which entity is being
         --  referenced.)

         Set_Analyzed (N, True);
         return;
      end Resolution_Failed;

   --  Start of processing for Resolve

   begin
      if N = Error then
         return;
      end if;

      --  Access attribute on remote subprogram cannot be used for a non-remote
      --  access-to-subprogram type.

      if Nkind (N) = N_Attribute_Reference
        and then Nam_In (Attribute_Name (N), Name_Access,
                                             Name_Unrestricted_Access,
                                             Name_Unchecked_Access)
        and then Comes_From_Source (N)
        and then Is_Entity_Name (Prefix (N))
        and then Is_Subprogram (Entity (Prefix (N)))
        and then Is_Remote_Call_Interface (Entity (Prefix (N)))
        and then not Is_Remote_Access_To_Subprogram_Type (Typ)
      then
         Error_Msg_N
           ("prefix must statically denote a non-remote subprogram", N);
      end if;

      From_Lib := Comes_From_Predefined_Lib_Unit (N);

      --  If the context is a Remote_Access_To_Subprogram, access attributes
      --  must be resolved with the corresponding fat pointer. There is no need
      --  to check for the attribute name since the return type of an
      --  attribute is never a remote type.

      if Nkind (N) = N_Attribute_Reference
        and then Comes_From_Source (N)
        and then (Is_Remote_Call_Interface (Typ) or else Is_Remote_Types (Typ))
      then
         declare
            Attr      : constant Attribute_Id :=
                          Get_Attribute_Id (Attribute_Name (N));
            Pref      : constant Node_Id      := Prefix (N);
            Decl      : Node_Id;
            Spec      : Node_Id;
            Is_Remote : Boolean := True;

         begin
            --  Check that Typ is a remote access-to-subprogram type

            if Is_Remote_Access_To_Subprogram_Type (Typ) then

               --  Prefix (N) must statically denote a remote subprogram
               --  declared in a package specification.

               if Attr = Attribute_Access           or else
                  Attr = Attribute_Unchecked_Access or else
                  Attr = Attribute_Unrestricted_Access
               then
                  Decl := Unit_Declaration_Node (Entity (Pref));

                  if Nkind (Decl) = N_Subprogram_Body then
                     Spec := Corresponding_Spec (Decl);

                     if Present (Spec) then
                        Decl := Unit_Declaration_Node (Spec);
                     end if;
                  end if;

                  Spec := Parent (Decl);

                  if not Is_Entity_Name (Prefix (N))
                    or else Nkind (Spec) /= N_Package_Specification
                    or else
                      not Is_Remote_Call_Interface (Defining_Entity (Spec))
                  then
                     Is_Remote := False;
                     Error_Msg_N
                       ("prefix must statically denote a remote subprogram ",
                        N);
                  end if;

                  --  If we are generating code in distributed mode, perform
                  --  semantic checks against corresponding remote entities.

                  if Expander_Active
                    and then Get_PCS_Name /= Name_No_DSA
                  then
                     Check_Subtype_Conformant
                       (New_Id  => Entity (Prefix (N)),
                        Old_Id  => Designated_Type
                                     (Corresponding_Remote_Type (Typ)),
                        Err_Loc => N);

                     if Is_Remote then
                        Process_Remote_AST_Attribute (N, Typ);
                     end if;
                  end if;
               end if;
            end if;
         end;
      end if;

      Debug_A_Entry ("resolving  ", N);

      if Debug_Flag_V then
         Write_Overloads (N);
      end if;

      if Comes_From_Source (N) then
         if Is_Fixed_Point_Type (Typ) then
            Check_Restriction (No_Fixed_Point, N);

         elsif Is_Floating_Point_Type (Typ)
           and then Typ /= Universal_Real
           and then Typ /= Any_Real
         then
            Check_Restriction (No_Floating_Point, N);
         end if;
      end if;

      --  Return if already analyzed

      if Analyzed (N) then
         Debug_A_Exit ("resolving  ", N, "  (done, already analyzed)");
         Analyze_Dimension (N);
         return;

      --  Any case of Any_Type as the Etype value means that we had a
      --  previous error.

      elsif Etype (N) = Any_Type then
         Debug_A_Exit ("resolving  ", N, "  (done, Etype = Any_Type)");
         return;
      end if;

      Check_Parameterless_Call (N);

      --  The resolution of an Expression_With_Actions is determined by
      --  its Expression.

      if Nkind (N) = N_Expression_With_Actions then
         Resolve (Expression (N), Typ);

         Found := True;
         Expr_Type := Etype (Expression (N));

      --  If not overloaded, then we know the type, and all that needs doing
      --  is to check that this type is compatible with the context.

      elsif not Is_Overloaded (N) then
         Found := Covers (Typ, Etype (N));
         Expr_Type := Etype (N);

      --  In the overloaded case, we must select the interpretation that
      --  is compatible with the context (i.e. the type passed to Resolve)

      else
         --  Loop through possible interpretations

         Get_First_Interp (N, I, It);
         Interp_Loop : while Present (It.Typ) loop
            if Debug_Flag_V then
               Write_Str ("Interp: ");
               Write_Interp (It);
            end if;

            --  We are only interested in interpretations that are compatible
            --  with the expected type, any other interpretations are ignored.

            if not Covers (Typ, It.Typ) then
               if Debug_Flag_V then
                  Write_Str ("    interpretation incompatible with context");
                  Write_Eol;
               end if;

            else
               --  Skip the current interpretation if it is disabled by an
               --  abstract operator. This action is performed only when the
               --  type against which we are resolving is the same as the
               --  type of the interpretation.

               if Ada_Version >= Ada_2005
                 and then It.Typ = Typ
                 and then Typ /= Universal_Integer
                 and then Typ /= Universal_Real
                 and then Present (It.Abstract_Op)
               then
                  if Debug_Flag_V then
                     Write_Line ("Skip.");
                  end if;

                  goto Continue;
               end if;

               --  First matching interpretation

               if not Found then
                  Found := True;
                  I1    := I;
                  Seen  := It.Nam;
                  Expr_Type := It.Typ;

               --  Matching interpretation that is not the first, maybe an
               --  error, but there are some cases where preference rules are
               --  used to choose between the two possibilities. These and
               --  some more obscure cases are handled in Disambiguate.

               else
                  --  If the current statement is part of a predefined library
                  --  unit, then all interpretations which come from user level
                  --  packages should not be considered. Check previous and
                  --  current one.

                  if From_Lib then
                     if not Comes_From_Predefined_Lib_Unit (It.Nam) then
                        goto Continue;

                     elsif not Comes_From_Predefined_Lib_Unit (Seen) then

                        --  Previous interpretation must be discarded

                        I1 := I;
                        Seen := It.Nam;
                        Expr_Type := It.Typ;
                        Set_Entity (N, Seen);
                        goto Continue;
                     end if;
                  end if;

                  --  Otherwise apply further disambiguation steps

                  Error_Msg_Sloc := Sloc (Seen);
                  It1 := Disambiguate (N, I1, I, Typ);

                  --  Disambiguation has succeeded. Skip the remaining
                  --  interpretations.

                  if It1 /= No_Interp then
                     Seen := It1.Nam;
                     Expr_Type := It1.Typ;

                     while Present (It.Typ) loop
                        Get_Next_Interp (I, It);
                     end loop;

                  else
                     --  Before we issue an ambiguity complaint, check for the
                     --  case of a subprogram call where at least one of the
                     --  arguments is Any_Type, and if so suppress the message,
                     --  since it is a cascaded error. This can also happen for
                     --  a generalized indexing operation.

                     if Nkind (N) in N_Subprogram_Call
                       or else (Nkind (N) = N_Indexed_Component
                                 and then Present (Generalized_Indexing (N)))
                     then
                        declare
                           A : Node_Id;
                           E : Node_Id;

                        begin
                           if Nkind (N) = N_Indexed_Component then
                              Rewrite (N, Generalized_Indexing (N));
                           end if;

                           A := First_Actual (N);
                           while Present (A) loop
                              E := A;

                              if Nkind (E) = N_Parameter_Association then
                                 E := Explicit_Actual_Parameter (E);
                              end if;

                              if Etype (E) = Any_Type then
                                 if Debug_Flag_V then
                                    Write_Str ("Any_Type in call");
                                    Write_Eol;
                                 end if;

                                 exit Interp_Loop;
                              end if;

                              Next_Actual (A);
                           end loop;
                        end;

                     elsif Nkind (N) in N_Binary_Op
                       and then (Etype (Left_Opnd (N)) = Any_Type
                                  or else Etype (Right_Opnd (N)) = Any_Type)
                     then
                        exit Interp_Loop;

                     elsif Nkind (N) in N_Unary_Op
                       and then Etype (Right_Opnd (N)) = Any_Type
                     then
                        exit Interp_Loop;
                     end if;

                     --  Not that special case, so issue message using the flag
                     --  Ambiguous to control printing of the header message
                     --  only at the start of an ambiguous set.

                     if not Ambiguous then
                        if Nkind (N) = N_Function_Call
                          and then Nkind (Name (N)) = N_Explicit_Dereference
                        then
                           Error_Msg_N
                             ("ambiguous expression (cannot resolve indirect "
                              & "call)!", N);
                        else
                           Error_Msg_NE -- CODEFIX
                             ("ambiguous expression (cannot resolve&)!",
                              N, It.Nam);
                        end if;

                        Ambiguous := True;

                        if Nkind (Parent (Seen)) = N_Full_Type_Declaration then
                           Error_Msg_N
                             ("\\possible interpretation (inherited)#!", N);
                        else
                           Error_Msg_N -- CODEFIX
                             ("\\possible interpretation#!", N);
                        end if;

                        if Nkind (N) in N_Subprogram_Call
                          and then Present (Parameter_Associations (N))
                        then
                           Report_Ambiguous_Argument;
                        end if;
                     end if;

                     Error_Msg_Sloc := Sloc (It.Nam);

                     --  By default, the error message refers to the candidate
                     --  interpretation. But if it is a predefined operator, it
                     --  is implicitly declared at the declaration of the type
                     --  of the operand. Recover the sloc of that declaration
                     --  for the error message.

                     if Nkind (N) in N_Op
                       and then Scope (It.Nam) = Standard_Standard
                       and then not Is_Overloaded (Right_Opnd (N))
                       and then Scope (Base_Type (Etype (Right_Opnd (N)))) /=
                                                             Standard_Standard
                     then
                        Err_Type := First_Subtype (Etype (Right_Opnd (N)));

                        if Comes_From_Source (Err_Type)
                          and then Present (Parent (Err_Type))
                        then
                           Error_Msg_Sloc := Sloc (Parent (Err_Type));
                        end if;

                     elsif Nkind (N) in N_Binary_Op
                       and then Scope (It.Nam) = Standard_Standard
                       and then not Is_Overloaded (Left_Opnd (N))
                       and then Scope (Base_Type (Etype (Left_Opnd (N)))) /=
                                                             Standard_Standard
                     then
                        Err_Type := First_Subtype (Etype (Left_Opnd (N)));

                        if Comes_From_Source (Err_Type)
                          and then Present (Parent (Err_Type))
                        then
                           Error_Msg_Sloc := Sloc (Parent (Err_Type));
                        end if;

                     --  If this is an indirect call, use the subprogram_type
                     --  in the message, to have a meaningful location. Also
                     --  indicate if this is an inherited operation, created
                     --  by a type declaration.

                     elsif Nkind (N) = N_Function_Call
                       and then Nkind (Name (N)) = N_Explicit_Dereference
                       and then Is_Type (It.Nam)
                     then
                        Err_Type := It.Nam;
                        Error_Msg_Sloc :=
                          Sloc (Associated_Node_For_Itype (Err_Type));
                     else
                        Err_Type := Empty;
                     end if;

                     if Nkind (N) in N_Op
                       and then Scope (It.Nam) = Standard_Standard
                       and then Present (Err_Type)
                     then
                        --  Special-case the message for universal_fixed
                        --  operators, which are not declared with the type
                        --  of the operand, but appear forever in Standard.

                        if It.Typ = Universal_Fixed
                          and then Scope (It.Nam) = Standard_Standard
                        then
                           Error_Msg_N
                             ("\\possible interpretation as universal_fixed "
                              & "operation (RM 4.5.5 (19))", N);
                        else
                           Error_Msg_N
                             ("\\possible interpretation (predefined)#!", N);
                        end if;

                     elsif
                       Nkind (Parent (It.Nam)) = N_Full_Type_Declaration
                     then
                        Error_Msg_N
                          ("\\possible interpretation (inherited)#!", N);
                     else
                        Error_Msg_N -- CODEFIX
                          ("\\possible interpretation#!", N);
                     end if;

                  end if;
               end if;

               --  We have a matching interpretation, Expr_Type is the type
               --  from this interpretation, and Seen is the entity.

               --  For an operator, just set the entity name. The type will be
               --  set by the specific operator resolution routine.

               if Nkind (N) in N_Op then
                  Set_Entity (N, Seen);
                  Generate_Reference (Seen, N);

               elsif Nkind_In (N, N_Case_Expression,
                                  N_Character_Literal,
                                  N_Delta_Aggregate,
                                  N_If_Expression)
               then
                  Set_Etype (N, Expr_Type);

               --  AI05-0139-2: Expression is overloaded because type has
               --  implicit dereference. The context may be the one that
               --  requires implicit dereferemce.

               elsif Has_Implicit_Dereference (Expr_Type) then
                  Set_Etype (N, Expr_Type);
                  Set_Is_Overloaded (N, False);

               --  If the expression is an entity, generate a reference
               --  to it, as this is not done for an overloaded construct
               --  during analysis.

                  if Is_Entity_Name (N)
                    and then Comes_From_Source (N)
                  then
                     Generate_Reference (Entity (N), N);

                     --  Examine access discriminants of entity type,
                     --  to check whether one of them yields the
                     --  expected type.

                     declare
                        Disc : Entity_Id :=
                          First_Discriminant (Etype (Entity (N)));

                     begin
                        while Present (Disc) loop
                           exit when Is_Access_Type (Etype (Disc))
                             and then Has_Implicit_Dereference (Disc)
                             and then Designated_Type (Etype (Disc)) = Typ;

                           Next_Discriminant (Disc);
                        end loop;

                        if Present (Disc) then
                           Build_Explicit_Dereference (N, Disc);
                        end if;
                     end;
                  end if;

                  exit Interp_Loop;

               elsif Is_Overloaded (N)
                 and then Present (It.Nam)
                 and then Ekind (It.Nam) = E_Discriminant
                 and then Has_Implicit_Dereference (It.Nam)
               then
                  --  If the node is a general indexing, the dereference is
                  --  is inserted when resolving the rewritten form, else
                  --  insert it now.

                  if Nkind (N) /= N_Indexed_Component
                    or else No (Generalized_Indexing (N))
                  then
                     Build_Explicit_Dereference (N, It.Nam);
                  end if;

               --  For an explicit dereference, attribute reference, range,
               --  short-circuit form (which is not an operator node), or call
               --  with a name that is an explicit dereference, there is
               --  nothing to be done at this point.

               elsif Nkind_In (N, N_Attribute_Reference,
                                  N_And_Then,
                                  N_Explicit_Dereference,
                                  N_Identifier,
                                  N_Indexed_Component,
                                  N_Or_Else,
                                  N_Range,
                                  N_Selected_Component,
                                  N_Slice)
                 or else Nkind (Name (N)) = N_Explicit_Dereference
               then
                  null;

               --  For procedure or function calls, set the type of the name,
               --  and also the entity pointer for the prefix.

               elsif Nkind (N) in N_Subprogram_Call
                 and then Is_Entity_Name (Name (N))
               then
                  Set_Etype  (Name (N), Expr_Type);
                  Set_Entity (Name (N), Seen);
                  Generate_Reference (Seen, Name (N));

               elsif Nkind (N) = N_Function_Call
                 and then Nkind (Name (N)) = N_Selected_Component
               then
                  Set_Etype (Name (N), Expr_Type);
                  Set_Entity (Selector_Name (Name (N)), Seen);
                  Generate_Reference (Seen, Selector_Name (Name (N)));

               --  For all other cases, just set the type of the Name

               else
                  Set_Etype (Name (N), Expr_Type);
               end if;

            end if;

            <<Continue>>

            --  Move to next interpretation

            exit Interp_Loop when No (It.Typ);

            Get_Next_Interp (I, It);
         end loop Interp_Loop;
      end if;

      --  At this stage Found indicates whether or not an acceptable
      --  interpretation exists. If not, then we have an error, except that if
      --  the context is Any_Type as a result of some other error, then we
      --  suppress the error report.

      if not Found then
         if Typ /= Any_Type then

            --  If type we are looking for is Void, then this is the procedure
            --  call case, and the error is simply that what we gave is not a
            --  procedure name (we think of procedure calls as expressions with
            --  types internally, but the user doesn't think of them this way).

            if Typ = Standard_Void_Type then

               --  Special case message if function used as a procedure

               if Nkind (N) = N_Procedure_Call_Statement
                 and then Is_Entity_Name (Name (N))
                 and then Ekind (Entity (Name (N))) = E_Function
               then
                  Error_Msg_NE
                    ("cannot use call to function & as a statement",
                     Name (N), Entity (Name (N)));
                  Error_Msg_N
                    ("\return value of a function call cannot be ignored",
                     Name (N));

               --  Otherwise give general message (not clear what cases this
               --  covers, but no harm in providing for them).

               else
                  Error_Msg_N ("expect procedure name in procedure call", N);
               end if;

               Found := True;

            --  Otherwise we do have a subexpression with the wrong type

            --  Check for the case of an allocator which uses an access type
            --  instead of the designated type. This is a common error and we
            --  specialize the message, posting an error on the operand of the
            --  allocator, complaining that we expected the designated type of
            --  the allocator.

            elsif Nkind (N) = N_Allocator
              and then Is_Access_Type (Typ)
              and then Is_Access_Type (Etype (N))
              and then Designated_Type (Etype (N)) = Typ
            then
               Wrong_Type (Expression (N), Designated_Type (Typ));
               Found := True;

            --  Check for view mismatch on Null in instances, for which the
            --  view-swapping mechanism has no identifier.

            elsif (In_Instance or else In_Inlined_Body)
              and then (Nkind (N) = N_Null)
              and then Is_Private_Type (Typ)
              and then Is_Access_Type (Full_View (Typ))
            then
               Resolve (N, Full_View (Typ));
               Set_Etype (N, Typ);
               return;

            --  Check for an aggregate. Sometimes we can get bogus aggregates
            --  from misuse of parentheses, and we are about to complain about
            --  the aggregate without even looking inside it.

            --  Instead, if we have an aggregate of type Any_Composite, then
            --  analyze and resolve the component fields, and then only issue
            --  another message if we get no errors doing this (otherwise
            --  assume that the errors in the aggregate caused the problem).

            elsif Nkind (N) = N_Aggregate
              and then Etype (N) = Any_Composite
            then
               --  Disable expansion in any case. If there is a type mismatch
               --  it may be fatal to try to expand the aggregate. The flag
               --  would otherwise be set to false when the error is posted.

               Expander_Active := False;

               declare
                  procedure Check_Aggr (Aggr : Node_Id);
                  --  Check one aggregate, and set Found to True if we have a
                  --  definite error in any of its elements

                  procedure Check_Elmt (Aelmt : Node_Id);
                  --  Check one element of aggregate and set Found to True if
                  --  we definitely have an error in the element.

                  ----------------
                  -- Check_Aggr --
                  ----------------

                  procedure Check_Aggr (Aggr : Node_Id) is
                     Elmt : Node_Id;

                  begin
                     if Present (Expressions (Aggr)) then
                        Elmt := First (Expressions (Aggr));
                        while Present (Elmt) loop
                           Check_Elmt (Elmt);
                           Next (Elmt);
                        end loop;
                     end if;

                     if Present (Component_Associations (Aggr)) then
                        Elmt := First (Component_Associations (Aggr));
                        while Present (Elmt) loop

                           --  If this is a default-initialized component, then
                           --  there is nothing to check. The box will be
                           --  replaced by the appropriate call during late
                           --  expansion.

                           if Nkind (Elmt) /= N_Iterated_Component_Association
                             and then not Box_Present (Elmt)
                           then
                              Check_Elmt (Expression (Elmt));
                           end if;

                           Next (Elmt);
                        end loop;
                     end if;
                  end Check_Aggr;

                  ----------------
                  -- Check_Elmt --
                  ----------------

                  procedure Check_Elmt (Aelmt : Node_Id) is
                  begin
                     --  If we have a nested aggregate, go inside it (to
                     --  attempt a naked analyze-resolve of the aggregate can
                     --  cause undesirable cascaded errors). Do not resolve
                     --  expression if it needs a type from context, as for
                     --  integer * fixed expression.

                     if Nkind (Aelmt) = N_Aggregate then
                        Check_Aggr (Aelmt);

                     else
                        Analyze (Aelmt);

                        if not Is_Overloaded (Aelmt)
                          and then Etype (Aelmt) /= Any_Fixed
                        then
                           Resolve (Aelmt);
                        end if;

                        if Etype (Aelmt) = Any_Type then
                           Found := True;
                        end if;
                     end if;
                  end Check_Elmt;

               begin
                  Check_Aggr (N);
               end;
            end if;

            --  Looks like we have a type error, but check for special case
            --  of Address wanted, integer found, with the configuration pragma
            --  Allow_Integer_Address active. If we have this case, introduce
            --  an unchecked conversion to allow the integer expression to be
            --  treated as an Address. The reverse case of integer wanted,
            --  Address found, is treated in an analogous manner.

            if Address_Integer_Convert_OK (Typ, Etype (N)) then
               Rewrite (N, Unchecked_Convert_To (Typ, Relocate_Node (N)));
               Analyze_And_Resolve (N, Typ);
               return;

            --  Under relaxed RM semantics silently replace occurrences of null
            --  by System.Address_Null.

            elsif Null_To_Null_Address_Convert_OK (N, Typ) then
               Replace_Null_By_Null_Address (N);
               Analyze_And_Resolve (N, Typ);
               return;
            end if;

            --  That special Allow_Integer_Address check did not apply, so we
            --  have a real type error. If an error message was issued already,
            --  Found got reset to True, so if it's still False, issue standard
            --  Wrong_Type message.

            if not Found then
               if Is_Overloaded (N) and then Nkind (N) = N_Function_Call then
                  declare
                     Subp_Name : Node_Id;

                  begin
                     if Is_Entity_Name (Name (N)) then
                        Subp_Name := Name (N);

                     elsif Nkind (Name (N)) = N_Selected_Component then

                        --  Protected operation: retrieve operation name

                        Subp_Name := Selector_Name (Name (N));

                     else
                        raise Program_Error;
                     end if;

                     Error_Msg_Node_2 := Typ;
                     Error_Msg_NE
                       ("no visible interpretation of& matches expected type&",
                        N, Subp_Name);
                  end;

                  if All_Errors_Mode then
                     declare
                        Index : Interp_Index;
                        It    : Interp;

                     begin
                        Error_Msg_N ("\\possible interpretations:", N);

                        Get_First_Interp (Name (N), Index, It);
                        while Present (It.Nam) loop
                           Error_Msg_Sloc := Sloc (It.Nam);
                           Error_Msg_Node_2 := It.Nam;
                           Error_Msg_NE
                             ("\\  type& for & declared#", N, It.Typ);
                           Get_Next_Interp (Index, It);
                        end loop;
                     end;

                  else
                     Error_Msg_N ("\use -gnatf for details", N);
                  end if;

               else
                  Wrong_Type (N, Typ);
               end if;
            end if;
         end if;

         Resolution_Failed;
         return;

      --  Test if we have more than one interpretation for the context

      elsif Ambiguous then
         Resolution_Failed;
         return;

      --  Only one intepretation

      else
         --  In Ada 2005, if we have something like "X : T := 2 + 2;", where
         --  the "+" on T is abstract, and the operands are of universal type,
         --  the above code will have (incorrectly) resolved the "+" to the
         --  universal one in Standard. Therefore check for this case and give
         --  an error. We can't do this earlier, because it would cause legal
         --  cases to get errors (when some other type has an abstract "+").

         if Ada_Version >= Ada_2005
           and then Nkind (N) in N_Op
           and then Is_Overloaded (N)
           and then Is_Universal_Numeric_Type (Etype (Entity (N)))
         then
            Get_First_Interp (N, I, It);
            while Present (It.Typ) loop
               if Present (It.Abstract_Op) and then
                 Etype (It.Abstract_Op) = Typ
               then
                  Error_Msg_NE
                    ("cannot call abstract subprogram &!", N, It.Abstract_Op);
                  return;
               end if;

               Get_Next_Interp (I, It);
            end loop;
         end if;

         --  Here we have an acceptable interpretation for the context

         --  Propagate type information and normalize tree for various
         --  predefined operations. If the context only imposes a class of
         --  types, rather than a specific type, propagate the actual type
         --  downward.

         if Typ = Any_Integer or else
            Typ = Any_Boolean or else
            Typ = Any_Modular or else
            Typ = Any_Real    or else
            Typ = Any_Discrete
         then
            Ctx_Type := Expr_Type;

            --  Any_Fixed is legal in a real context only if a specific fixed-
            --  point type is imposed. If Norman Cohen can be confused by this,
            --  it deserves a separate message.

            if Typ = Any_Real
              and then Expr_Type = Any_Fixed
            then
               Error_Msg_N ("illegal context for mixed mode operation", N);
               Set_Etype (N, Universal_Real);
               Ctx_Type := Universal_Real;
            end if;
         end if;

         --  A user-defined operator is transformed into a function call at
         --  this point, so that further processing knows that operators are
         --  really operators (i.e. are predefined operators). User-defined
         --  operators that are intrinsic are just renamings of the predefined
         --  ones, and need not be turned into calls either, but if they rename
         --  a different operator, we must transform the node accordingly.
         --  Instantiations of Unchecked_Conversion are intrinsic but are
         --  treated as functions, even if given an operator designator.

         if Nkind (N) in N_Op
           and then Present (Entity (N))
           and then Ekind (Entity (N)) /= E_Operator
         then
            if not Is_Predefined_Op (Entity (N)) then
               Rewrite_Operator_As_Call (N, Entity (N));

            elsif Present (Alias (Entity (N)))
              and then
                Nkind (Parent (Parent (Entity (N)))) =
                                    N_Subprogram_Renaming_Declaration
            then
               Rewrite_Renamed_Operator (N, Alias (Entity (N)), Typ);

               --  If the node is rewritten, it will be fully resolved in
               --  Rewrite_Renamed_Operator.

               if Analyzed (N) then
                  return;
               end if;
            end if;
         end if;

         case N_Subexpr'(Nkind (N)) is
            when N_Aggregate =>
               Resolve_Aggregate                 (N, Ctx_Type);

            when N_Allocator =>
               Resolve_Allocator                 (N, Ctx_Type);

            when N_Short_Circuit =>
               Resolve_Short_Circuit             (N, Ctx_Type);

            when N_Attribute_Reference =>
               Resolve_Attribute                 (N, Ctx_Type);

            when N_Case_Expression =>
               Resolve_Case_Expression           (N, Ctx_Type);

            when N_Character_Literal =>
               Resolve_Character_Literal         (N, Ctx_Type);

            when N_Delta_Aggregate =>
               Resolve_Delta_Aggregate           (N, Ctx_Type);

            when N_Expanded_Name =>
               Resolve_Entity_Name               (N, Ctx_Type);

            when N_Explicit_Dereference =>
               Resolve_Explicit_Dereference      (N, Ctx_Type);

            when N_Expression_With_Actions =>
               Resolve_Expression_With_Actions   (N, Ctx_Type);

            when N_Extension_Aggregate =>
               Resolve_Extension_Aggregate       (N, Ctx_Type);

            when N_Function_Call =>
               Resolve_Call                      (N, Ctx_Type);

            when N_Identifier =>
               Resolve_Entity_Name               (N, Ctx_Type);

            when N_If_Expression =>
               Resolve_If_Expression             (N, Ctx_Type);

            when N_Indexed_Component =>
               Resolve_Indexed_Component         (N, Ctx_Type);

            when N_Integer_Literal =>
               Resolve_Integer_Literal           (N, Ctx_Type);

            when N_Membership_Test =>
               Resolve_Membership_Op             (N, Ctx_Type);

            when N_Null =>
               Resolve_Null                      (N, Ctx_Type);

            when N_Op_And
               | N_Op_Or
               | N_Op_Xor
            =>
               Resolve_Logical_Op                (N, Ctx_Type);

            when N_Op_Eq
               | N_Op_Ne
            =>
               Resolve_Equality_Op               (N, Ctx_Type);

            when N_Op_Ge
               | N_Op_Gt
               | N_Op_Le
               | N_Op_Lt
            =>
               Resolve_Comparison_Op             (N, Ctx_Type);

            when N_Op_Not =>
               Resolve_Op_Not                    (N, Ctx_Type);

            when N_Op_Add
               | N_Op_Divide
               | N_Op_Mod
               | N_Op_Multiply
               | N_Op_Rem
               | N_Op_Subtract
            =>
               Resolve_Arithmetic_Op             (N, Ctx_Type);

            when N_Op_Concat =>
               Resolve_Op_Concat                 (N, Ctx_Type);

            when N_Op_Expon =>
               Resolve_Op_Expon                  (N, Ctx_Type);

            when N_Op_Abs
               | N_Op_Minus
               | N_Op_Plus
            =>
               Resolve_Unary_Op                  (N, Ctx_Type);

            when N_Op_Shift =>
               Resolve_Shift                     (N, Ctx_Type);

            when N_Procedure_Call_Statement =>
               Resolve_Call                      (N, Ctx_Type);

            when N_Operator_Symbol =>
               Resolve_Operator_Symbol           (N, Ctx_Type);

            when N_Qualified_Expression =>
               Resolve_Qualified_Expression      (N, Ctx_Type);

            --  Why is the following null, needs a comment ???

            when N_Quantified_Expression =>
               null;

            when N_Raise_Expression =>
               Resolve_Raise_Expression          (N, Ctx_Type);

            when N_Raise_xxx_Error =>
               Set_Etype (N, Ctx_Type);

            when N_Range =>
               Resolve_Range                     (N, Ctx_Type);

            when N_Real_Literal =>
               Resolve_Real_Literal              (N, Ctx_Type);

            when N_Reference =>
               Resolve_Reference                 (N, Ctx_Type);

            when N_Selected_Component =>
               Resolve_Selected_Component        (N, Ctx_Type);

            when N_Slice =>
               Resolve_Slice                     (N, Ctx_Type);

            when N_String_Literal =>
               Resolve_String_Literal            (N, Ctx_Type);

            when N_Target_Name =>
               Resolve_Target_Name               (N, Ctx_Type);

            when N_Type_Conversion =>
               Resolve_Type_Conversion           (N, Ctx_Type);

            when N_Unchecked_Expression =>
               Resolve_Unchecked_Expression      (N, Ctx_Type);

            when N_Unchecked_Type_Conversion =>
               Resolve_Unchecked_Type_Conversion (N, Ctx_Type);
         end case;

         --  Mark relevant use-type and use-package clauses as effective using
         --  the original node because constant folding may have occured and
         --  removed references that need to be examined.

         if Nkind (Original_Node (N)) in N_Op then
            Mark_Use_Clauses (Original_Node (N));
         end if;

         --  Ada 2012 (AI05-0149): Apply an (implicit) conversion to an
         --  expression of an anonymous access type that occurs in the context
         --  of a named general access type, except when the expression is that
         --  of a membership test. This ensures proper legality checking in
         --  terms of allowed conversions (expressions that would be illegal to
         --  convert implicitly are allowed in membership tests).

         if Ada_Version >= Ada_2012
           and then Ekind (Base_Type (Ctx_Type)) = E_General_Access_Type
           and then Ekind (Etype (N)) = E_Anonymous_Access_Type
           and then Nkind (Parent (N)) not in N_Membership_Test
         then
            Rewrite (N, Convert_To (Ctx_Type, Relocate_Node (N)));
            Analyze_And_Resolve (N, Ctx_Type);
         end if;

         --  If the subexpression was replaced by a non-subexpression, then
         --  all we do is to expand it. The only legitimate case we know of
         --  is converting procedure call statement to entry call statements,
         --  but there may be others, so we are making this test general.

         if Nkind (N) not in N_Subexpr then
            Debug_A_Exit ("resolving  ", N, "  (done)");
            Expand (N);
            return;
         end if;

         --  The expression is definitely NOT overloaded at this point, so
         --  we reset the Is_Overloaded flag to avoid any confusion when
         --  reanalyzing the node.

         Set_Is_Overloaded (N, False);

         --  Freeze expression type, entity if it is a name, and designated
         --  type if it is an allocator (RM 13.14(10,11,13)).

         --  Now that the resolution of the type of the node is complete, and
         --  we did not detect an error, we can expand this node. We skip the
         --  expand call if we are in a default expression, see section
         --  "Handling of Default Expressions" in Sem spec.

         Debug_A_Exit ("resolving  ", N, "  (done)");

         --  We unconditionally freeze the expression, even if we are in
         --  default expression mode (the Freeze_Expression routine tests this
         --  flag and only freezes static types if it is set).

         --  Ada 2012 (AI05-177): The declaration of an expression function
         --  does not cause freezing, but we never reach here in that case.
         --  Here we are resolving the corresponding expanded body, so we do
         --  need to perform normal freezing.

         --  As elsewhere we do not emit freeze node within a generic. We make
         --  an exception for entities that are expressions, only to detect
         --  misuses of deferred constants and preserve the output of various
         --  tests.

         if not Inside_A_Generic or else Is_Entity_Name (N) then
            Freeze_Expression (N);
         end if;

         --  Now we can do the expansion

         Expand (N);
      end if;
   end Resolve;

   -------------
   -- Resolve --
   -------------

   --  Version with check(s) suppressed

   procedure Resolve (N : Node_Id; Typ : Entity_Id; Suppress : Check_Id) is
   begin
      if Suppress = All_Checks then
         declare
            Sva : constant Suppress_Array := Scope_Suppress.Suppress;
         begin
            Scope_Suppress.Suppress := (others => True);
            Resolve (N, Typ);
            Scope_Suppress.Suppress := Sva;
         end;

      else
         declare
            Svg : constant Boolean := Scope_Suppress.Suppress (Suppress);
         begin
            Scope_Suppress.Suppress (Suppress) := True;
            Resolve (N, Typ);
            Scope_Suppress.Suppress (Suppress) := Svg;
         end;
      end if;
   end Resolve;

   -------------
   -- Resolve --
   -------------

   --  Version with implicit type

   procedure Resolve (N : Node_Id) is
   begin
      Resolve (N, Etype (N));
   end Resolve;

   ---------------------
   -- Resolve_Actuals --
   ---------------------

   procedure Resolve_Actuals (N : Node_Id; Nam : Entity_Id) is
      Loc    : constant Source_Ptr := Sloc (N);
      A      : Node_Id;
      A_Id   : Entity_Id;
      A_Typ  : Entity_Id := Empty; -- init to avoid warning
      F      : Entity_Id;
      F_Typ  : Entity_Id;
      Prev   : Node_Id := Empty;
      Orig_A : Node_Id;
      Real_F : Entity_Id := Empty; -- init to avoid warning

      Real_Subp : Entity_Id;
      --  If the subprogram being called is an inherited operation for
      --  a formal derived type in an instance, Real_Subp is the subprogram
      --  that will be called. It may have different formal names than the
      --  operation of the formal in the generic, so after actual is resolved
      --  the name of the actual in a named association must carry the name
      --  of the actual of the subprogram being called.

      procedure Check_Aliased_Parameter;
      --  Check rules on aliased parameters and related accessibility rules
      --  in (RM 3.10.2 (10.2-10.4)).

      procedure Check_Argument_Order;
      --  Performs a check for the case where the actuals are all simple
      --  identifiers that correspond to the formal names, but in the wrong
      --  order, which is considered suspicious and cause for a warning.

      procedure Check_Prefixed_Call;
      --  If the original node is an overloaded call in prefix notation,
      --  insert an 'Access or a dereference as needed over the first actual.
      --  Try_Object_Operation has already verified that there is a valid
      --  interpretation, but the form of the actual can only be determined
      --  once the primitive operation is identified.

      procedure Flag_Effectively_Volatile_Objects (Expr : Node_Id);
      --  Emit an error concerning the illegal usage of an effectively volatile
      --  object in interfering context (SPARK RM 7.13(12)).

      procedure Insert_Default;
      --  If the actual is missing in a call, insert in the actuals list
      --  an instance of the default expression. The insertion is always
      --  a named association.

      function Same_Ancestor (T1, T2 : Entity_Id) return Boolean;
      --  Check whether T1 and T2, or their full views, are derived from a
      --  common type. Used to enforce the restrictions on array conversions
      --  of AI95-00246.

      function Static_Concatenation (N : Node_Id) return Boolean;
      --  Predicate to determine whether an actual that is a concatenation
      --  will be evaluated statically and does not need a transient scope.
      --  This must be determined before the actual is resolved and expanded
      --  because if needed the transient scope must be introduced earlier.

      -----------------------------
      -- Check_Aliased_Parameter --
      -----------------------------

      procedure Check_Aliased_Parameter is
         Nominal_Subt : Entity_Id;

      begin
         if Is_Aliased (F) then
            if Is_Tagged_Type (A_Typ) then
               null;

            elsif Is_Aliased_View (A) then
               if Is_Constr_Subt_For_U_Nominal (A_Typ) then
                  Nominal_Subt := Base_Type (A_Typ);
               else
                  Nominal_Subt := A_Typ;
               end if;

               if Subtypes_Statically_Match (F_Typ, Nominal_Subt) then
                  null;

               --  In a generic body assume the worst for generic formals:
               --  they can have a constrained partial view (AI05-041).

               elsif Has_Discriminants (F_Typ)
                 and then not Is_Constrained (F_Typ)
                 and then not Has_Constrained_Partial_View (F_Typ)
                 and then not Is_Generic_Type (F_Typ)
               then
                  null;

               else
                  Error_Msg_NE ("untagged actual does not match "
                                & "aliased formal&", A, F);
               end if;

            else
               Error_Msg_NE ("actual for aliased formal& must be "
                             & "aliased object", A, F);
            end if;

            if Ekind (Nam) = E_Procedure then
               null;

            elsif Ekind (Etype (Nam)) = E_Anonymous_Access_Type then
               if Nkind (Parent (N)) = N_Type_Conversion
                 and then Type_Access_Level (Etype (Parent (N))) <
                                                        Object_Access_Level (A)
               then
                  Error_Msg_N ("aliased actual has wrong accessibility", A);
               end if;

            elsif Nkind (Parent (N)) = N_Qualified_Expression
              and then Nkind (Parent (Parent (N))) = N_Allocator
              and then Type_Access_Level (Etype (Parent (Parent (N)))) <
                                                        Object_Access_Level (A)
            then
               Error_Msg_N
                 ("aliased actual in allocator has wrong accessibility", A);
            end if;
         end if;
      end Check_Aliased_Parameter;

      --------------------------
      -- Check_Argument_Order --
      --------------------------

      procedure Check_Argument_Order is
      begin
         --  Nothing to do if no parameters, or original node is neither a
         --  function call nor a procedure call statement (happens in the
         --  operator-transformed-to-function call case), or the call is to an
         --  operator symbol (which is usually in infix form), or the call does
         --  not come from source, or this warning is off.

         if not Warn_On_Parameter_Order
           or else No (Parameter_Associations (N))
           or else Nkind (Original_Node (N)) not in N_Subprogram_Call
           or else (Nkind (Name (N)) = N_Identifier
                     and then Present (Entity (Name (N)))
                     and then Nkind (Entity (Name (N))) =
                                N_Defining_Operator_Symbol)
           or else not Comes_From_Source (N)
         then
            return;
         end if;

         declare
            Nargs : constant Nat := List_Length (Parameter_Associations (N));

         begin
            --  Nothing to do if only one parameter

            if Nargs < 2 then
               return;
            end if;

            --  Here if at least two arguments

            declare
               Actuals : array (1 .. Nargs) of Node_Id;
               Actual  : Node_Id;
               Formal  : Node_Id;

               Wrong_Order : Boolean := False;
               --  Set True if an out of order case is found

            begin
               --  Collect identifier names of actuals, fail if any actual is
               --  not a simple identifier, and record max length of name.

               Actual := First (Parameter_Associations (N));
               for J in Actuals'Range loop
                  if Nkind (Actual) /= N_Identifier then
                     return;
                  else
                     Actuals (J) := Actual;
                     Next (Actual);
                  end if;
               end loop;

               --  If we got this far, all actuals are identifiers and the list
               --  of their names is stored in the Actuals array.

               Formal := First_Formal (Nam);
               for J in Actuals'Range loop

                  --  If we ran out of formals, that's odd, probably an error
                  --  which will be detected elsewhere, but abandon the search.

                  if No (Formal) then
                     return;
                  end if;

                  --  If name matches and is in order OK

                  if Chars (Formal) = Chars (Actuals (J)) then
                     null;

                  else
                     --  If no match, see if it is elsewhere in list and if so
                     --  flag potential wrong order if type is compatible.

                     for K in Actuals'Range loop
                        if Chars (Formal) = Chars (Actuals (K))
                          and then
                            Has_Compatible_Type (Actuals (K), Etype (Formal))
                        then
                           Wrong_Order := True;
                           goto Continue;
                        end if;
                     end loop;

                     --  No match

                     return;
                  end if;

                  <<Continue>> Next_Formal (Formal);
               end loop;

               --  If Formals left over, also probably an error, skip warning

               if Present (Formal) then
                  return;
               end if;

               --  Here we give the warning if something was out of order

               if Wrong_Order then
                  Error_Msg_N
                    ("?P?actuals for this call may be in wrong order", N);
               end if;
            end;
         end;
      end Check_Argument_Order;

      -------------------------
      -- Check_Prefixed_Call --
      -------------------------

      procedure Check_Prefixed_Call is
         Act    : constant Node_Id   := First_Actual (N);
         A_Type : constant Entity_Id := Etype (Act);
         F_Type : constant Entity_Id := Etype (First_Formal (Nam));
         Orig   : constant Node_Id := Original_Node (N);
         New_A  : Node_Id;

      begin
         --  Check whether the call is a prefixed call, with or without
         --  additional actuals.

         if Nkind (Orig) = N_Selected_Component
           or else
             (Nkind (Orig) = N_Indexed_Component
               and then Nkind (Prefix (Orig)) = N_Selected_Component
               and then Is_Entity_Name (Prefix (Prefix (Orig)))
               and then Is_Entity_Name (Act)
               and then Chars (Act) = Chars (Prefix (Prefix (Orig))))
         then
            if Is_Access_Type (A_Type)
              and then not Is_Access_Type (F_Type)
            then
               --  Introduce dereference on object in prefix

               New_A :=
                 Make_Explicit_Dereference (Sloc (Act),
                   Prefix => Relocate_Node (Act));
               Rewrite (Act, New_A);
               Analyze (Act);

            elsif Is_Access_Type (F_Type)
              and then not Is_Access_Type (A_Type)
            then
               --  Introduce an implicit 'Access in prefix

               if not Is_Aliased_View (Act) then
                  Error_Msg_NE
                    ("object in prefixed call to& must be aliased "
                     & "(RM 4.1.3 (13 1/2))",
                    Prefix (Act), Nam);
               end if;

               Rewrite (Act,
                 Make_Attribute_Reference (Loc,
                   Attribute_Name => Name_Access,
                   Prefix         => Relocate_Node (Act)));
            end if;

            Analyze (Act);
         end if;
      end Check_Prefixed_Call;

      ---------------------------------------
      -- Flag_Effectively_Volatile_Objects --
      ---------------------------------------

      procedure Flag_Effectively_Volatile_Objects (Expr : Node_Id) is
         function Flag_Object (N : Node_Id) return Traverse_Result;
         --  Determine whether arbitrary node N denotes an effectively volatile
         --  object and if it does, emit an error.

         -----------------
         -- Flag_Object --
         -----------------

         function Flag_Object (N : Node_Id) return Traverse_Result is
            Id : Entity_Id;

         begin
            --  Do not consider nested function calls because they have already
            --  been processed during their own resolution.

            if Nkind (N) = N_Function_Call then
               return Skip;

            elsif Is_Entity_Name (N) and then Present (Entity (N)) then
               Id := Entity (N);

               if Is_Object (Id)
                 and then Is_Effectively_Volatile (Id)
                 and then (Async_Writers_Enabled (Id)
                            or else Effective_Reads_Enabled (Id))
               then
                  Error_Msg_N
                    ("volatile object cannot appear in this context (SPARK "
                     & "RM 7.1.3(11))", N);
                  return Skip;
               end if;
            end if;

            return OK;
         end Flag_Object;

         procedure Flag_Objects is new Traverse_Proc (Flag_Object);

      --  Start of processing for Flag_Effectively_Volatile_Objects

      begin
         Flag_Objects (Expr);
      end Flag_Effectively_Volatile_Objects;

      --------------------
      -- Insert_Default --
      --------------------

      procedure Insert_Default is
         Actval : Node_Id;
         Assoc  : Node_Id;

      begin
         --  Missing argument in call, nothing to insert

         if No (Default_Value (F)) then
            return;

         else
            --  Note that we do a full New_Copy_Tree, so that any associated
            --  Itypes are properly copied. This may not be needed any more,
            --  but it does no harm as a safety measure. Defaults of a generic
            --  formal may be out of bounds of the corresponding actual (see
            --  cc1311b) and an additional check may be required.

            Actval :=
              New_Copy_Tree
                (Default_Value (F),
                 New_Scope => Current_Scope,
                 New_Sloc  => Loc);

            --  Propagate dimension information, if any.

            Copy_Dimensions (Default_Value (F), Actval);

            if Is_Concurrent_Type (Scope (Nam))
              and then Has_Discriminants (Scope (Nam))
            then
               Replace_Actual_Discriminants (N, Actval);
            end if;

            if Is_Overloadable (Nam)
              and then Present (Alias (Nam))
            then
               if Base_Type (Etype (F)) /= Base_Type (Etype (Actval))
                 and then not Is_Tagged_Type (Etype (F))
               then
                  --  If default is a real literal, do not introduce a
                  --  conversion whose effect may depend on the run-time
                  --  size of universal real.

                  if Nkind (Actval) = N_Real_Literal then
                     Set_Etype (Actval, Base_Type (Etype (F)));
                  else
                     Actval := Unchecked_Convert_To (Etype (F), Actval);
                  end if;
               end if;

               if Is_Scalar_Type (Etype (F)) then
                  Enable_Range_Check (Actval);
               end if;

               Set_Parent (Actval, N);

               --  Resolve aggregates with their base type, to avoid scope
               --  anomalies: the subtype was first built in the subprogram
               --  declaration, and the current call may be nested.

               if Nkind (Actval) = N_Aggregate then
                  Analyze_And_Resolve (Actval, Etype (F));
               else
                  Analyze_And_Resolve (Actval, Etype (Actval));
               end if;

            else
               Set_Parent (Actval, N);

               --  See note above concerning aggregates

               if Nkind (Actval) = N_Aggregate
                 and then Has_Discriminants (Etype (Actval))
               then
                  Analyze_And_Resolve (Actval, Base_Type (Etype (Actval)));

               --  Resolve entities with their own type, which may differ from
               --  the type of a reference in a generic context (the view
               --  swapping mechanism did not anticipate the re-analysis of
               --  default values in calls).

               elsif Is_Entity_Name (Actval) then
                  Analyze_And_Resolve (Actval, Etype (Entity (Actval)));

               else
                  Analyze_And_Resolve (Actval, Etype (Actval));
               end if;
            end if;

            --  If default is a tag indeterminate function call, propagate tag
            --  to obtain proper dispatching.

            if Is_Controlling_Formal (F)
              and then Nkind (Default_Value (F)) = N_Function_Call
            then
               Set_Is_Controlling_Actual (Actval);
            end if;
         end if;

         --  If the default expression raises constraint error, then just
         --  silently replace it with an N_Raise_Constraint_Error node, since
         --  we already gave the warning on the subprogram spec. If node is
         --  already a Raise_Constraint_Error leave as is, to prevent loops in
         --  the warnings removal machinery.

         if Raises_Constraint_Error (Actval)
           and then Nkind (Actval) /= N_Raise_Constraint_Error
         then
            Rewrite (Actval,
              Make_Raise_Constraint_Error (Loc,
                Reason => CE_Range_Check_Failed));

            Set_Raises_Constraint_Error (Actval);
            Set_Etype (Actval, Etype (F));
         end if;

         Assoc :=
           Make_Parameter_Association (Loc,
             Explicit_Actual_Parameter => Actval,
             Selector_Name             => Make_Identifier (Loc, Chars (F)));

         --  Case of insertion is first named actual

         if No (Prev)
           or else Nkind (Parent (Prev)) /= N_Parameter_Association
         then
            Set_Next_Named_Actual (Assoc, First_Named_Actual (N));
            Set_First_Named_Actual (N, Actval);

            if No (Prev) then
               if No (Parameter_Associations (N)) then
                  Set_Parameter_Associations (N, New_List (Assoc));
               else
                  Append (Assoc, Parameter_Associations (N));
               end if;

            else
               Insert_After (Prev, Assoc);
            end if;

         --  Case of insertion is not first named actual

         else
            Set_Next_Named_Actual
              (Assoc, Next_Named_Actual (Parent (Prev)));
            Set_Next_Named_Actual (Parent (Prev), Actval);
            Append (Assoc, Parameter_Associations (N));
         end if;

         Mark_Rewrite_Insertion (Assoc);
         Mark_Rewrite_Insertion (Actval);

         Prev := Actval;
      end Insert_Default;

      -------------------
      -- Same_Ancestor --
      -------------------

      function Same_Ancestor (T1, T2 : Entity_Id) return Boolean is
         FT1 : Entity_Id := T1;
         FT2 : Entity_Id := T2;

      begin
         if Is_Private_Type (T1)
           and then Present (Full_View (T1))
         then
            FT1 := Full_View (T1);
         end if;

         if Is_Private_Type (T2)
           and then Present (Full_View (T2))
         then
            FT2 := Full_View (T2);
         end if;

         return Root_Type (Base_Type (FT1)) = Root_Type (Base_Type (FT2));
      end Same_Ancestor;

      --------------------------
      -- Static_Concatenation --
      --------------------------

      function Static_Concatenation (N : Node_Id) return Boolean is
      begin
         case Nkind (N) is
            when N_String_Literal =>
               return True;

            when N_Op_Concat =>

               --  Concatenation is static when both operands are static and
               --  the concatenation operator is a predefined one.

               return Scope (Entity (N)) = Standard_Standard
                        and then
                      Static_Concatenation (Left_Opnd (N))
                        and then
                      Static_Concatenation (Right_Opnd (N));

            when others =>
               if Is_Entity_Name (N) then
                  declare
                     Ent : constant Entity_Id := Entity (N);
                  begin
                     return Ekind (Ent) = E_Constant
                              and then Present (Constant_Value (Ent))
                              and then
                                Is_OK_Static_Expression (Constant_Value (Ent));
                  end;

               else
                  return False;
               end if;
         end case;
      end Static_Concatenation;

   --  Start of processing for Resolve_Actuals

   begin
      Check_Argument_Order;

      if Is_Overloadable (Nam)
        and then Is_Inherited_Operation (Nam)
        and then In_Instance
        and then Present (Alias (Nam))
        and then Present (Overridden_Operation (Alias (Nam)))
      then
         Real_Subp := Alias (Nam);
      else
         Real_Subp := Empty;
      end if;

      if Present (First_Actual (N)) then
         Check_Prefixed_Call;
      end if;

      A := First_Actual (N);
      F := First_Formal (Nam);

      if Present (Real_Subp) then
         Real_F := First_Formal (Real_Subp);
      end if;

      while Present (F) loop
         if No (A) and then Needs_No_Actuals (Nam) then
            null;

         --  If we have an error in any actual or formal, indicated by a type
         --  of Any_Type, then abandon resolution attempt, and set result type
         --  to Any_Type. Skip this if the actual is a Raise_Expression, whose
         --  type is imposed from context.

         elsif (Present (A) and then Etype (A) = Any_Type)
           or else Etype (F) = Any_Type
         then
            if Nkind (A) /= N_Raise_Expression then
               Set_Etype (N, Any_Type);
               return;
            end if;
         end if;

         --  Case where actual is present

         --  If the actual is an entity, generate a reference to it now. We
         --  do this before the actual is resolved, because a formal of some
         --  protected subprogram, or a task discriminant, will be rewritten
         --  during expansion, and the source entity reference may be lost.

         if Present (A)
           and then Is_Entity_Name (A)
           and then Comes_From_Source (A)
         then
            --  Annotate the tree by creating a variable reference marker when
            --  the actual denotes a variable reference, in case the reference
            --  is folded or optimized away. The variable reference marker is
            --  automatically saved for later examination by the ABE Processing
            --  phase. The status of the reference is set as follows:

            --    status   mode
            --    read     IN, IN OUT
            --    write    IN OUT, OUT

            if Needs_Variable_Reference_Marker
                 (N        => A,
                  Calls_OK => True)
            then
               Build_Variable_Reference_Marker
                 (N     => A,
                  Read  => Ekind (F) /= E_Out_Parameter,
                  Write => Ekind (F) /= E_In_Parameter);
            end if;

            Orig_A := Entity (A);

            if Present (Orig_A) then
               if Is_Formal (Orig_A)
                 and then Ekind (F) /= E_In_Parameter
               then
                  Generate_Reference (Orig_A, A, 'm');

               elsif not Is_Overloaded (A) then
                  if Ekind (F) /= E_Out_Parameter then
                     Generate_Reference (Orig_A, A);

                  --  RM 6.4.1(12): For an out parameter that is passed by
                  --  copy, the formal parameter object is created, and:

                  --  * For an access type, the formal parameter is initialized
                  --    from the value of the actual, without checking that the
                  --    value satisfies any constraint, any predicate, or any
                  --    exclusion of the null value.

                  --  * For a scalar type that has the Default_Value aspect
                  --    specified, the formal parameter is initialized from the
                  --    value of the actual, without checking that the value
                  --    satisfies any constraint or any predicate.
                  --  I do not understand why this case is included??? this is
                  --  not a case where an OUT parameter is treated as IN OUT.

                  --  * For a composite type with discriminants or that has
                  --    implicit initial values for any subcomponents, the
                  --    behavior is as for an in out parameter passed by copy.

                  --  Hence for these cases we generate the read reference now
                  --  (the write reference will be generated later by
                  --   Note_Possible_Modification).

                  elsif Is_By_Copy_Type (Etype (F))
                    and then
                      (Is_Access_Type (Etype (F))
                         or else
                           (Is_Scalar_Type (Etype (F))
                              and then
                                Present (Default_Aspect_Value (Etype (F))))
                         or else
                           (Is_Composite_Type (Etype (F))
                              and then (Has_Discriminants (Etype (F))
                                         or else Is_Partially_Initialized_Type
                                                   (Etype (F)))))
                  then
                     Generate_Reference (Orig_A, A);
                  end if;
               end if;
            end if;
         end if;

         if Present (A)
           and then (Nkind (Parent (A)) /= N_Parameter_Association
                      or else Chars (Selector_Name (Parent (A))) = Chars (F))
         then
            --  If style checking mode on, check match of formal name

            if Style_Check then
               if Nkind (Parent (A)) = N_Parameter_Association then
                  Check_Identifier (Selector_Name (Parent (A)), F);
               end if;
            end if;

            --  If the formal is Out or In_Out, do not resolve and expand the
            --  conversion, because it is subsequently expanded into explicit
            --  temporaries and assignments. However, the object of the
            --  conversion can be resolved. An exception is the case of tagged
            --  type conversion with a class-wide actual. In that case we want
            --  the tag check to occur and no temporary will be needed (no
            --  representation change can occur) and the parameter is passed by
            --  reference, so we go ahead and resolve the type conversion.
            --  Another exception is the case of reference to component or
            --  subcomponent of a bit-packed array, in which case we want to
            --  defer expansion to the point the in and out assignments are
            --  performed.

            if Ekind (F) /= E_In_Parameter
              and then Nkind (A) = N_Type_Conversion
              and then not Is_Class_Wide_Type (Etype (Expression (A)))
              and then not Is_Interface (Etype (A))
            then
               if Ekind (F) = E_In_Out_Parameter
                 and then Is_Array_Type (Etype (F))
               then
                  --  In a view conversion, the conversion must be legal in
                  --  both directions, and thus both component types must be
                  --  aliased, or neither (4.6 (8)).

                  --  The extra rule in 4.6 (24.9.2) seems unduly restrictive:
                  --  the privacy requirement should not apply to generic
                  --  types, and should be checked in an instance. ARG query
                  --  is in order ???

                  if Has_Aliased_Components (Etype (Expression (A))) /=
                     Has_Aliased_Components (Etype (F))
                  then
                     Error_Msg_N
                       ("both component types in a view conversion must be"
                         & " aliased, or neither", A);

                  --  Comment here??? what set of cases???

                  elsif
                     not Same_Ancestor (Etype (F), Etype (Expression (A)))
                  then
                     --  Check view conv between unrelated by ref array types

                     if Is_By_Reference_Type (Etype (F))
                        or else Is_By_Reference_Type (Etype (Expression (A)))
                     then
                        Error_Msg_N
                          ("view conversion between unrelated by reference "
                           & "array types not allowed (\'A'I-00246)", A);

                     --  In Ada 2005 mode, check view conversion component
                     --  type cannot be private, tagged, or volatile. Note
                     --  that we only apply this to source conversions. The
                     --  generated code can contain conversions which are
                     --  not subject to this test, and we cannot extract the
                     --  component type in such cases since it is not present.

                     elsif Comes_From_Source (A)
                       and then Ada_Version >= Ada_2005
                     then
                        declare
                           Comp_Type : constant Entity_Id :=
                                         Component_Type
                                           (Etype (Expression (A)));
                        begin
                           if (Is_Private_Type (Comp_Type)
                                 and then not Is_Generic_Type (Comp_Type))
                             or else Is_Tagged_Type (Comp_Type)
                             or else Is_Volatile (Comp_Type)
                           then
                              Error_Msg_N
                                ("component type of a view conversion cannot"
                                   & " be private, tagged, or volatile"
                                   & " (RM 4.6 (24))",
                                   Expression (A));
                           end if;
                        end;
                     end if;
                  end if;
               end if;

               --  Resolve expression if conversion is all OK

               if (Conversion_OK (A)
                    or else Valid_Conversion (A, Etype (A), Expression (A)))
                 and then not Is_Ref_To_Bit_Packed_Array (Expression (A))
               then
                  Resolve (Expression (A));
               end if;

            --  If the actual is a function call that returns a limited
            --  unconstrained object that needs finalization, create a
            --  transient scope for it, so that it can receive the proper
            --  finalization list.

            elsif Expander_Active
              and then Nkind (A) = N_Function_Call
              and then Is_Limited_Record (Etype (F))
              and then not Is_Constrained (Etype (F))
              and then (Needs_Finalization (Etype (F))
                         or else Has_Task (Etype (F)))
            then
               Establish_Transient_Scope (A, Manage_Sec_Stack => False);
               Resolve (A, Etype (F));

            --  A small optimization: if one of the actuals is a concatenation
            --  create a block around a procedure call to recover stack space.
            --  This alleviates stack usage when several procedure calls in
            --  the same statement list use concatenation. We do not perform
            --  this wrapping for code statements, where the argument is a
            --  static string, and we want to preserve warnings involving
            --  sequences of such statements.

            elsif Expander_Active
              and then Nkind (A) = N_Op_Concat
              and then Nkind (N) = N_Procedure_Call_Statement
              and then not (Is_Intrinsic_Subprogram (Nam)
                             and then Chars (Nam) = Name_Asm)
              and then not Static_Concatenation (A)
            then
               Establish_Transient_Scope (A, Manage_Sec_Stack => False);
               Resolve (A, Etype (F));

            else
               if Nkind (A) = N_Type_Conversion
                 and then Is_Array_Type (Etype (F))
                 and then not Same_Ancestor (Etype (F), Etype (Expression (A)))
                 and then
                   (Is_Limited_Type (Etype (F))
                     or else Is_Limited_Type (Etype (Expression (A))))
               then
                  Error_Msg_N
                    ("conversion between unrelated limited array types not "
                     & "allowed ('A'I-00246)", A);

                  if Is_Limited_Type (Etype (F)) then
                     Explain_Limited_Type (Etype (F), A);
                  end if;

                  if Is_Limited_Type (Etype (Expression (A))) then
                     Explain_Limited_Type (Etype (Expression (A)), A);
                  end if;
               end if;

               --  (Ada 2005: AI-251): If the actual is an allocator whose
               --  directly designated type is a class-wide interface, we build
               --  an anonymous access type to use it as the type of the
               --  allocator. Later, when the subprogram call is expanded, if
               --  the interface has a secondary dispatch table the expander
               --  will add a type conversion to force the correct displacement
               --  of the pointer.

               if Nkind (A) = N_Allocator then
                  declare
                     DDT : constant Entity_Id :=
                             Directly_Designated_Type (Base_Type (Etype (F)));

                  begin
                     --  Displace the pointer to the object to reference its
                     --  secondary dispatch table.

                     if Is_Class_Wide_Type (DDT)
                       and then Is_Interface (DDT)
                     then
                        Rewrite (A, Convert_To (Etype (F), Relocate_Node (A)));
                        Analyze_And_Resolve (A, Etype (F),
                          Suppress => Access_Check);
                     end if;

                     --  Ada 2005, AI-162:If the actual is an allocator, the
                     --  innermost enclosing statement is the master of the
                     --  created object. This needs to be done with expansion
                     --  enabled only, otherwise the transient scope will not
                     --  be removed in the expansion of the wrapped construct.

                     if Expander_Active
                       and then (Needs_Finalization (DDT)
                                  or else Has_Task (DDT))
                     then
                        Establish_Transient_Scope
                          (A, Manage_Sec_Stack => False);
                     end if;
                  end;

                  if Ekind (Etype (F)) = E_Anonymous_Access_Type then
                     Check_Restriction (No_Access_Parameter_Allocators, A);
                  end if;
               end if;

               --  (Ada 2005): The call may be to a primitive operation of a
               --  tagged synchronized type, declared outside of the type. In
               --  this case the controlling actual must be converted to its
               --  corresponding record type, which is the formal type. The
               --  actual may be a subtype, either because of a constraint or
               --  because it is a generic actual, so use base type to locate
               --  concurrent type.

               F_Typ := Base_Type (Etype (F));

               if Is_Tagged_Type (F_Typ)
                 and then (Is_Concurrent_Type (F_Typ)
                            or else Is_Concurrent_Record_Type (F_Typ))
               then
                  --  If the actual is overloaded, look for an interpretation
                  --  that has a synchronized type.

                  if not Is_Overloaded (A) then
                     A_Typ := Base_Type (Etype (A));

                  else
                     declare
                        Index : Interp_Index;
                        It    : Interp;

                     begin
                        Get_First_Interp (A, Index, It);
                        while Present (It.Typ) loop
                           if Is_Concurrent_Type (It.Typ)
                             or else Is_Concurrent_Record_Type (It.Typ)
                           then
                              A_Typ := Base_Type (It.Typ);
                              exit;
                           end if;

                           Get_Next_Interp (Index, It);
                        end loop;
                     end;
                  end if;

                  declare
                     Full_A_Typ : Entity_Id;

                  begin
                     if Present (Full_View (A_Typ)) then
                        Full_A_Typ := Base_Type (Full_View (A_Typ));
                     else
                        Full_A_Typ := A_Typ;
                     end if;

                     --  Tagged synchronized type (case 1): the actual is a
                     --  concurrent type.

                     if Is_Concurrent_Type (A_Typ)
                       and then Corresponding_Record_Type (A_Typ) = F_Typ
                     then
                        Rewrite (A,
                          Unchecked_Convert_To
                            (Corresponding_Record_Type (A_Typ), A));
                        Resolve (A, Etype (F));

                     --  Tagged synchronized type (case 2): the formal is a
                     --  concurrent type.

                     elsif Ekind (Full_A_Typ) = E_Record_Type
                       and then Present
                               (Corresponding_Concurrent_Type (Full_A_Typ))
                       and then Is_Concurrent_Type (F_Typ)
                       and then Present (Corresponding_Record_Type (F_Typ))
                       and then Full_A_Typ = Corresponding_Record_Type (F_Typ)
                     then
                        Resolve (A, Corresponding_Record_Type (F_Typ));

                     --  Common case

                     else
                        Resolve (A, Etype (F));
                     end if;
                  end;

               --  Not a synchronized operation

               else
                  Resolve (A, Etype (F));
               end if;
            end if;

            A_Typ := Etype (A);
            F_Typ := Etype (F);

            --  An actual cannot be an untagged formal incomplete type

            if Ekind (A_Typ) = E_Incomplete_Type
              and then not Is_Tagged_Type (A_Typ)
              and then Is_Generic_Type (A_Typ)
            then
               Error_Msg_N
                 ("invalid use of untagged formal incomplete type", A);
            end if;

            if Comes_From_Source (Original_Node (N))
              and then Nkind_In (Original_Node (N), N_Function_Call,
                                                    N_Procedure_Call_Statement)
            then
               --  In formal mode, check that actual parameters matching
               --  formals of tagged types are objects (or ancestor type
               --  conversions of objects), not general expressions.

               if Is_Actual_Tagged_Parameter (A) then
                  if Is_SPARK_05_Object_Reference (A) then
                     null;

                  elsif Nkind (A) = N_Type_Conversion then
                     declare
                        Operand     : constant Node_Id   := Expression (A);
                        Operand_Typ : constant Entity_Id := Etype (Operand);
                        Target_Typ  : constant Entity_Id := A_Typ;

                     begin
                        if not Is_SPARK_05_Object_Reference (Operand) then
                           Check_SPARK_05_Restriction
                             ("object required", Operand);

                        --  In formal mode, the only view conversions are those
                        --  involving ancestor conversion of an extended type.

                        elsif not
                          (Is_Tagged_Type (Target_Typ)
                           and then not Is_Class_Wide_Type (Target_Typ)
                           and then Is_Tagged_Type (Operand_Typ)
                           and then not Is_Class_Wide_Type (Operand_Typ)
                           and then Is_Ancestor (Target_Typ, Operand_Typ))
                        then
                           if Ekind_In
                             (F, E_Out_Parameter, E_In_Out_Parameter)
                           then
                              Check_SPARK_05_Restriction
                                ("ancestor conversion is the only permitted "
                                 & "view conversion", A);
                           else
                              Check_SPARK_05_Restriction
                                ("ancestor conversion required", A);
                           end if;

                        else
                           null;
                        end if;
                     end;

                  else
                     Check_SPARK_05_Restriction ("object required", A);
                  end if;

               --  In formal mode, the only view conversions are those
               --  involving ancestor conversion of an extended type.

               elsif Nkind (A) = N_Type_Conversion
                 and then Ekind_In (F, E_Out_Parameter, E_In_Out_Parameter)
               then
                  Check_SPARK_05_Restriction
                    ("ancestor conversion is the only permitted view "
                     & "conversion", A);
               end if;
            end if;

            --  has warnings suppressed, then we reset Never_Set_In_Source for
            --  the calling entity. The reason for this is to catch cases like
            --  GNAT.Spitbol.Patterns.Vstring_Var where the called subprogram
            --  uses trickery to modify an IN parameter.

            if Ekind (F) = E_In_Parameter
              and then Is_Entity_Name (A)
              and then Present (Entity (A))
              and then Ekind (Entity (A)) = E_Variable
              and then Has_Warnings_Off (F_Typ)
            then
               Set_Never_Set_In_Source (Entity (A), False);
            end if;

            --  Perform error checks for IN and IN OUT parameters

            if Ekind (F) /= E_Out_Parameter then

               --  Check unset reference. For scalar parameters, it is clearly
               --  wrong to pass an uninitialized value as either an IN or
               --  IN-OUT parameter. For composites, it is also clearly an
               --  error to pass a completely uninitialized value as an IN
               --  parameter, but the case of IN OUT is trickier. We prefer
               --  not to give a warning here. For example, suppose there is
               --  a routine that sets some component of a record to False.
               --  It is perfectly reasonable to make this IN-OUT and allow
               --  either initialized or uninitialized records to be passed
               --  in this case.

               --  For partially initialized composite values, we also avoid
               --  warnings, since it is quite likely that we are passing a
               --  partially initialized value and only the initialized fields
               --  will in fact be read in the subprogram.

               if Is_Scalar_Type (A_Typ)
                 or else (Ekind (F) = E_In_Parameter
                           and then not Is_Partially_Initialized_Type (A_Typ))
               then
                  Check_Unset_Reference (A);
               end if;

               --  In Ada 83 we cannot pass an OUT parameter as an IN or IN OUT
               --  actual to a nested call, since this constitutes a reading of
               --  the parameter, which is not allowed.

               if Ada_Version = Ada_83
                 and then Is_Entity_Name (A)
                 and then Ekind (Entity (A)) = E_Out_Parameter
               then
                  Error_Msg_N ("(Ada 83) illegal reading of out parameter", A);
               end if;
            end if;

            --  In -gnatd.q mode, forget that a given array is constant when
            --  it is passed as an IN parameter to a foreign-convention
            --  subprogram. This is in case the subprogram evilly modifies the
            --  object. Of course, correct code would use IN OUT.

            if Debug_Flag_Dot_Q
              and then Ekind (F) = E_In_Parameter
              and then Has_Foreign_Convention (Nam)
              and then Is_Array_Type (F_Typ)
              and then Nkind (A) in N_Has_Entity
              and then Present (Entity (A))
            then
               Set_Is_True_Constant (Entity (A), False);
            end if;

            --  Case of OUT or IN OUT parameter

            if Ekind (F) /= E_In_Parameter then

               --  For an Out parameter, check for useless assignment. Note
               --  that we can't set Last_Assignment this early, because we may
               --  kill current values in Resolve_Call, and that call would
               --  clobber the Last_Assignment field.

               --  Note: call Warn_On_Useless_Assignment before doing the check
               --  below for Is_OK_Variable_For_Out_Formal so that the setting
               --  of Referenced_As_LHS/Referenced_As_Out_Formal properly
               --  reflects the last assignment, not this one.

               if Ekind (F) = E_Out_Parameter then
                  if Warn_On_Modified_As_Out_Parameter (F)
                    and then Is_Entity_Name (A)
                    and then Present (Entity (A))
                    and then Comes_From_Source (N)
                  then
                     Warn_On_Useless_Assignment (Entity (A), A);
                  end if;
               end if;

               --  Validate the form of the actual. Note that the call to
               --  Is_OK_Variable_For_Out_Formal generates the required
               --  reference in this case.

               --  A call to an initialization procedure for an aggregate
               --  component may initialize a nested component of a constant
               --  designated object. In this context the object is variable.

               if not Is_OK_Variable_For_Out_Formal (A)
                 and then not Is_Init_Proc (Nam)
               then
                  Error_Msg_NE ("actual for& must be a variable", A, F);

                  if Is_Subprogram (Current_Scope) then
                     if Is_Invariant_Procedure (Current_Scope)
                       or else Is_Partial_Invariant_Procedure (Current_Scope)
                     then
                        Error_Msg_N
                          ("function used in invariant cannot modify its "
                           & "argument", F);

                     elsif Is_Predicate_Function (Current_Scope) then
                        Error_Msg_N
                          ("function used in predicate cannot modify its "
                           & "argument", F);
                     end if;
                  end if;
               end if;

               --  What's the following about???

               if Is_Entity_Name (A) then
                  Kill_Checks (Entity (A));
               else
                  Kill_All_Checks;
               end if;
            end if;

            if A_Typ = Any_Type then
               Set_Etype (N, Any_Type);
               return;
            end if;

            --  Apply appropriate constraint/predicate checks for IN [OUT] case

            if Ekind_In (F, E_In_Parameter, E_In_Out_Parameter) then

               --  Apply predicate tests except in certain special cases. Note
               --  that it might be more consistent to apply these only when
               --  expansion is active (in Exp_Ch6.Expand_Actuals), as we do
               --  for the outbound predicate tests ??? In any case indicate
               --  the function being called, for better warnings if the call
               --  leads to an infinite recursion.

               if Predicate_Tests_On_Arguments (Nam) then
                  Apply_Predicate_Check (A, F_Typ, Nam);
               end if;

               --  Apply required constraint checks

               if Is_Scalar_Type (A_Typ) then
                  Apply_Scalar_Range_Check (A, F_Typ);

               elsif Is_Array_Type (A_Typ) then
                  Apply_Length_Check (A, F_Typ);

               elsif Is_Record_Type (F_Typ)
                 and then Has_Discriminants (F_Typ)
                 and then Is_Constrained (F_Typ)
                 and then (not Is_Derived_Type (F_Typ)
                            or else Comes_From_Source (Nam))
               then
                  Apply_Discriminant_Check (A, F_Typ);

                  --  For view conversions of a discriminated object, apply
                  --  check to object itself, the conversion alreay has the
                  --  proper type.

                  if Nkind (A) = N_Type_Conversion
                    and then Is_Constrained (Etype (Expression (A)))
                  then
                     Apply_Discriminant_Check (Expression (A), F_Typ);
                  end if;

               elsif Is_Access_Type (F_Typ)
                 and then Is_Array_Type (Designated_Type (F_Typ))
                 and then Is_Constrained (Designated_Type (F_Typ))
               then
                  Apply_Length_Check (A, F_Typ);

               elsif Is_Access_Type (F_Typ)
                 and then Has_Discriminants (Designated_Type (F_Typ))
                 and then Is_Constrained (Designated_Type (F_Typ))
               then
                  Apply_Discriminant_Check (A, F_Typ);

               else
                  Apply_Range_Check (A, F_Typ);
               end if;

               --  Ada 2005 (AI-231): Note that the controlling parameter case
               --  already existed in Ada 95, which is partially checked
               --  elsewhere (see Checks), and we don't want the warning
               --  message to differ.

               if Is_Access_Type (F_Typ)
                 and then Can_Never_Be_Null (F_Typ)
                 and then Known_Null (A)
               then
                  if Is_Controlling_Formal (F) then
                     Apply_Compile_Time_Constraint_Error
                       (N      => A,
                        Msg    => "null value not allowed here??",
                        Reason => CE_Access_Check_Failed);

                  elsif Ada_Version >= Ada_2005 then
                     Apply_Compile_Time_Constraint_Error
                       (N      => A,
                        Msg    => "(Ada 2005) null not allowed in "
                                  & "null-excluding formal??",
                        Reason => CE_Null_Not_Allowed);
                  end if;
               end if;
            end if;

            --  Checks for OUT parameters and IN OUT parameters

            if Ekind_In (F, E_Out_Parameter, E_In_Out_Parameter) then

               --  If there is a type conversion, make sure the return value
               --  meets the constraints of the variable before the conversion.

               if Nkind (A) = N_Type_Conversion then
                  if Is_Scalar_Type (A_Typ) then

                     --  Special case here tailored to Exp_Ch6.Is_Legal_Copy,
                     --  which would prevent the check from being generated.
                     --  This is for Starlet only though, so long obsolete.

                     if Mechanism (F) = By_Reference
                       and then Is_Valued_Procedure (Nam)
                     then
                        null;
                     else
                        Apply_Scalar_Range_Check
                          (Expression (A), Etype (Expression (A)), A_Typ);
                     end if;

                     --  In addition the return value must meet the constraints
                     --  of the object type (see the comment below).

                     Apply_Scalar_Range_Check (A, A_Typ, F_Typ);

                  else
                     Apply_Range_Check
                       (Expression (A), Etype (Expression (A)), A_Typ);
                  end if;

               --  If no conversion, apply scalar range checks and length check
               --  based on the subtype of the actual (NOT that of the formal).
               --  This indicates that the check takes place on return from the
               --  call. During expansion the required constraint checks are
               --  inserted. In GNATprove mode, in the absence of expansion,
               --  the flag indicates that the returned value is valid.

               else
                  if Is_Scalar_Type (F_Typ) then
                     Apply_Scalar_Range_Check (A, A_Typ, F_Typ);

                  elsif Is_Array_Type (F_Typ)
                    and then Ekind (F) = E_Out_Parameter
                  then
                     Apply_Length_Check (A, F_Typ);

                  else
                     Apply_Range_Check (A, A_Typ, F_Typ);
                  end if;
               end if;

               --  Note: we do not apply the predicate checks for the case of
               --  OUT and IN OUT parameters. They are instead applied in the
               --  Expand_Actuals routine in Exp_Ch6.
            end if;

            --  An actual associated with an access parameter is implicitly
            --  converted to the anonymous access type of the formal and must
            --  satisfy the legality checks for access conversions.

            if Ekind (F_Typ) = E_Anonymous_Access_Type then
               if not Valid_Conversion (A, F_Typ, A) then
                  Error_Msg_N
                    ("invalid implicit conversion for access parameter", A);
               end if;

               --  If the actual is an access selected component of a variable,
               --  the call may modify its designated object. It is reasonable
               --  to treat this as a potential modification of the enclosing
               --  record, to prevent spurious warnings that it should be
               --  declared as a constant, because intuitively programmers
               --  regard the designated subcomponent as part of the record.

               if Nkind (A) = N_Selected_Component
                 and then Is_Entity_Name (Prefix (A))
                 and then not Is_Constant_Object (Entity (Prefix (A)))
               then
                  Note_Possible_Modification (A, Sure => False);
               end if;
            end if;

            --  Check illegal cases of atomic/volatile actual (RM C.6(12,13))

            if (Is_By_Reference_Type (Etype (F)) or else Is_Aliased (F))
              and then Comes_From_Source (N)
            then
               if Is_Atomic_Object (A)
                 and then not Is_Atomic (Etype (F))
               then
                  Error_Msg_NE
                    ("cannot pass atomic object to nonatomic formal&",
                     A, F);
                  Error_Msg_N
                    ("\which is passed by reference (RM C.6(12))", A);

               elsif Is_Volatile_Object (A)
                 and then not Is_Volatile (Etype (F))
               then
                  Error_Msg_NE
                    ("cannot pass volatile object to nonvolatile formal&",
                     A, F);
                  Error_Msg_N
                    ("\which is passed by reference (RM C.6(12))", A);
               end if;

               if Ada_Version >= Ada_2020
                 and then Is_Subcomponent_Of_Atomic_Object (A)
                 and then not Is_Atomic_Object (A)
               then
                  Error_Msg_N
                    ("cannot pass nonatomic subcomponent of atomic object",
                     A);
                  Error_Msg_NE
                    ("\to formal & which is passed by reference (RM C.6(13))",
                     A, F);
               end if;
            end if;

            --  Check that subprograms don't have improper controlling
            --  arguments (RM 3.9.2 (9)).

            --  A primitive operation may have an access parameter of an
            --  incomplete tagged type, but a dispatching call is illegal
            --  if the type is still incomplete.

            if Is_Controlling_Formal (F) then
               Set_Is_Controlling_Actual (A);

               if Ekind (Etype (F)) = E_Anonymous_Access_Type then
                  declare
                     Desig : constant Entity_Id := Designated_Type (Etype (F));
                  begin
                     if Ekind (Desig) = E_Incomplete_Type
                       and then No (Full_View (Desig))
                       and then No (Non_Limited_View (Desig))
                     then
                        Error_Msg_NE
                          ("premature use of incomplete type& "
                           & "in dispatching call", A, Desig);
                     end if;
                  end;
               end if;

            elsif Nkind (A) = N_Explicit_Dereference then
               Validate_Remote_Access_To_Class_Wide_Type (A);
            end if;

            --  Apply legality rule 3.9.2  (9/1)

            if (Is_Class_Wide_Type (A_Typ) or else Is_Dynamically_Tagged (A))
              and then not Is_Class_Wide_Type (F_Typ)
              and then not Is_Controlling_Formal (F)
              and then not In_Instance
            then
               Error_Msg_N ("class-wide argument not allowed here!", A);

               if Is_Subprogram (Nam) and then Comes_From_Source (Nam) then
                  Error_Msg_Node_2 := F_Typ;
                  Error_Msg_NE
                    ("& is not a dispatching operation of &!", A, Nam);
               end if;

            --  Apply the checks described in 3.10.2(27): if the context is a
            --  specific access-to-object, the actual cannot be class-wide.
            --  Use base type to exclude access_to_subprogram cases.

            elsif Is_Access_Type (A_Typ)
              and then Is_Access_Type (F_Typ)
              and then not Is_Access_Subprogram_Type (Base_Type (F_Typ))
              and then (Is_Class_Wide_Type (Designated_Type (A_Typ))
                         or else (Nkind (A) = N_Attribute_Reference
                                   and then
                                     Is_Class_Wide_Type (Etype (Prefix (A)))))
              and then not Is_Class_Wide_Type (Designated_Type (F_Typ))
              and then not Is_Controlling_Formal (F)

              --  Disable these checks for call to imported C++ subprograms

              and then not
                (Is_Entity_Name (Name (N))
                  and then Is_Imported (Entity (Name (N)))
                  and then Convention (Entity (Name (N))) = Convention_CPP)
            then
               Error_Msg_N
                 ("access to class-wide argument not allowed here!", A);

               if Is_Subprogram (Nam) and then Comes_From_Source (Nam) then
                  Error_Msg_Node_2 := Designated_Type (F_Typ);
                  Error_Msg_NE
                    ("& is not a dispatching operation of &!", A, Nam);
               end if;
            end if;

            Check_Aliased_Parameter;

            Eval_Actual (A);

            --  If it is a named association, treat the selector_name as a
            --  proper identifier, and mark the corresponding entity.

            if Nkind (Parent (A)) = N_Parameter_Association

              --  Ignore reference in SPARK mode, as it refers to an entity not
              --  in scope at the point of reference, so the reference should
              --  be ignored for computing effects of subprograms.

              and then not GNATprove_Mode
            then
               --  If subprogram is overridden, use name of formal that
               --  is being called.

               if Present (Real_Subp) then
                  Set_Entity (Selector_Name (Parent (A)), Real_F);
                  Set_Etype (Selector_Name (Parent (A)), Etype (Real_F));

               else
                  Set_Entity (Selector_Name (Parent (A)), F);
                  Generate_Reference (F, Selector_Name (Parent (A)));
                  Set_Etype (Selector_Name (Parent (A)), F_Typ);
                  Generate_Reference (F_Typ, N, ' ');
               end if;
            end if;

            Prev := A;

            if Ekind (F) /= E_Out_Parameter then
               Check_Unset_Reference (A);
            end if;

            --  The following checks are only relevant when SPARK_Mode is on as
            --  they are not standard Ada legality rule. Internally generated
            --  temporaries are ignored.

            if SPARK_Mode = On and then Comes_From_Source (A) then

               --  An effectively volatile object may act as an actual when the
               --  corresponding formal is of a non-scalar effectively volatile
               --  type (SPARK RM 7.1.3(11)).

               if not Is_Scalar_Type (Etype (F))
                 and then Is_Effectively_Volatile (Etype (F))
               then
                  null;

               --  An effectively volatile object may act as an actual in a
               --  call to an instance of Unchecked_Conversion.
               --  (SPARK RM 7.1.3(11)).

               elsif Is_Unchecked_Conversion_Instance (Nam) then
                  null;

               --  The actual denotes an object

               elsif Is_Effectively_Volatile_Object (A) then
                  Error_Msg_N
                    ("volatile object cannot act as actual in a call (SPARK "
                     & "RM 7.1.3(11))", A);

               --  Otherwise the actual denotes an expression. Inspect the
               --  expression and flag each effectively volatile object with
               --  enabled property Async_Writers or Effective_Reads as illegal
               --  because it apprears within an interfering context. Note that
               --  this is usually done in Resolve_Entity_Name, but when the
               --  effectively volatile object appears as an actual in a call,
               --  the call must be resolved first.

               else
                  Flag_Effectively_Volatile_Objects (A);
               end if;

               --  An effectively volatile variable cannot act as an actual
               --  parameter in a procedure call when the variable has enabled
               --  property Effective_Reads and the corresponding formal is of
               --  mode IN (SPARK RM 7.1.3(10)).

               if Ekind (Nam) = E_Procedure
                 and then Ekind (F) = E_In_Parameter
                 and then Is_Entity_Name (A)
               then
                  A_Id := Entity (A);

                  if Ekind (A_Id) = E_Variable
                    and then Is_Effectively_Volatile (Etype (A_Id))
                    and then Effective_Reads_Enabled (A_Id)
                  then
                     Error_Msg_NE
                       ("effectively volatile variable & cannot appear as "
                        & "actual in procedure call", A, A_Id);

                     Error_Msg_Name_1 := Name_Effective_Reads;
                     Error_Msg_N ("\\variable has enabled property %", A);
                     Error_Msg_N ("\\corresponding formal has mode IN", A);
                  end if;
               end if;
            end if;

            --  A formal parameter of a specific tagged type whose related
            --  subprogram is subject to pragma Extensions_Visible with value
            --  "False" cannot act as an actual in a subprogram with value
            --  "True" (SPARK RM 6.1.7(3)).

            if Is_EVF_Expression (A)
              and then Extensions_Visible_Status (Nam) =
                       Extensions_Visible_True
            then
               Error_Msg_N
                 ("formal parameter cannot act as actual parameter when "
                  & "Extensions_Visible is False", A);
               Error_Msg_NE
                 ("\subprogram & has Extensions_Visible True", A, Nam);
            end if;

            --  The actual parameter of a Ghost subprogram whose formal is of
            --  mode IN OUT or OUT must be a Ghost variable (SPARK RM 6.9(12)).

            if Comes_From_Source (Nam)
              and then Is_Ghost_Entity (Nam)
              and then Ekind_In (F, E_In_Out_Parameter, E_Out_Parameter)
              and then Is_Entity_Name (A)
              and then Present (Entity (A))
              and then not Is_Ghost_Entity (Entity (A))
            then
               Error_Msg_NE
                 ("non-ghost variable & cannot appear as actual in call to "
                  & "ghost procedure", A, Entity (A));

               if Ekind (F) = E_In_Out_Parameter then
                  Error_Msg_N ("\corresponding formal has mode `IN OUT`", A);
               else
                  Error_Msg_N ("\corresponding formal has mode OUT", A);
               end if;
            end if;

            Next_Actual (A);

         --  Case where actual is not present

         else
            Insert_Default;
         end if;

         Next_Formal (F);

         if Present (Real_Subp) then
            Next_Formal (Real_F);
         end if;
      end loop;
   end Resolve_Actuals;

   -----------------------
   -- Resolve_Allocator --
   -----------------------

   procedure Resolve_Allocator (N : Node_Id; Typ : Entity_Id) is
      Desig_T  : constant Entity_Id := Designated_Type (Typ);
      E        : constant Node_Id   := Expression (N);
      Subtyp   : Entity_Id;
      Discrim  : Entity_Id;
      Constr   : Node_Id;
      Aggr     : Node_Id;
      Assoc    : Node_Id := Empty;
      Disc_Exp : Node_Id;

      procedure Check_Allocator_Discrim_Accessibility
        (Disc_Exp  : Node_Id;
         Alloc_Typ : Entity_Id);
      --  Check that accessibility level associated with an access discriminant
      --  initialized in an allocator by the expression Disc_Exp is not deeper
      --  than the level of the allocator type Alloc_Typ. An error message is
      --  issued if this condition is violated. Specialized checks are done for
      --  the cases of a constraint expression which is an access attribute or
      --  an access discriminant.

      procedure Check_Allocator_Discrim_Accessibility_Exprs
        (Curr_Exp  : Node_Id;
         Alloc_Typ : Entity_Id);
      --  Dispatch checks performed by Check_Allocator_Discrim_Accessibility
      --  across all expressions within a given conditional expression.

      function In_Dispatching_Context return Boolean;
      --  If the allocator is an actual in a call, it is allowed to be class-
      --  wide when the context is not because it is a controlling actual.

      -------------------------------------------
      -- Check_Allocator_Discrim_Accessibility --
      -------------------------------------------

      procedure Check_Allocator_Discrim_Accessibility
        (Disc_Exp  : Node_Id;
         Alloc_Typ : Entity_Id)
      is
      begin
         if Type_Access_Level (Etype (Disc_Exp)) >
            Deepest_Type_Access_Level (Alloc_Typ)
         then
            Error_Msg_N
              ("operand type has deeper level than allocator type", Disc_Exp);

         --  When the expression is an Access attribute the level of the prefix
         --  object must not be deeper than that of the allocator's type.

         elsif Nkind (Disc_Exp) = N_Attribute_Reference
           and then Get_Attribute_Id (Attribute_Name (Disc_Exp)) =
                      Attribute_Access
           and then Object_Access_Level (Prefix (Disc_Exp)) >
                      Deepest_Type_Access_Level (Alloc_Typ)
         then
            Error_Msg_N
              ("prefix of attribute has deeper level than allocator type",
               Disc_Exp);

         --  When the expression is an access discriminant the check is against
         --  the level of the prefix object.

         elsif Ekind (Etype (Disc_Exp)) = E_Anonymous_Access_Type
           and then Nkind (Disc_Exp) = N_Selected_Component
           and then Object_Access_Level (Prefix (Disc_Exp)) >
                      Deepest_Type_Access_Level (Alloc_Typ)
         then
            Error_Msg_N
              ("access discriminant has deeper level than allocator type",
               Disc_Exp);

         --  All other cases are legal

         else
            null;
         end if;
      end Check_Allocator_Discrim_Accessibility;

      -------------------------------------------------
      -- Check_Allocator_Discrim_Accessibility_Exprs --
      -------------------------------------------------

      procedure Check_Allocator_Discrim_Accessibility_Exprs
        (Curr_Exp  : Node_Id;
         Alloc_Typ : Entity_Id)
      is
         Alt      : Node_Id;
         Expr     : Node_Id;
         Disc_Exp : constant Node_Id := Original_Node (Curr_Exp);
      begin
         --  When conditional expressions are constant folded we know at
         --  compile time which expression to check - so don't bother with
         --  the rest of the cases.

         if Nkind (Curr_Exp) = N_Attribute_Reference then
            Check_Allocator_Discrim_Accessibility (Curr_Exp, Alloc_Typ);

         --  Non-constant-folded if expressions

         elsif Nkind (Disc_Exp) = N_If_Expression then
            --  Check both expressions if they are still present in the face
            --  of expansion.

            Expr := Next (First (Expressions (Disc_Exp)));
            if Present (Expr) then
               Check_Allocator_Discrim_Accessibility_Exprs (Expr, Alloc_Typ);
               Expr := Next (Expr);
               if Present (Expr) then
                  Check_Allocator_Discrim_Accessibility_Exprs
                    (Expr, Alloc_Typ);
               end if;
            end if;

         --  Non-constant-folded case expressions

         elsif Nkind (Disc_Exp) = N_Case_Expression then
            --  Check all alternatives

            Alt := First (Alternatives (Disc_Exp));
            while Present (Alt) loop
               Check_Allocator_Discrim_Accessibility_Exprs
                 (Expression (Alt), Alloc_Typ);

               Next (Alt);
            end loop;

         --  Base case, check the accessibility of the original node of the
         --  expression.

         else
            Check_Allocator_Discrim_Accessibility (Disc_Exp, Alloc_Typ);
         end if;
      end Check_Allocator_Discrim_Accessibility_Exprs;

      ----------------------------
      -- In_Dispatching_Context --
      ----------------------------

      function In_Dispatching_Context return Boolean is
         Par : constant Node_Id := Parent (N);

      begin
         return Nkind (Par) in N_Subprogram_Call
           and then Is_Entity_Name (Name (Par))
           and then Is_Dispatching_Operation (Entity (Name (Par)));
      end In_Dispatching_Context;

   --  Start of processing for Resolve_Allocator

   begin
      --  Replace general access with specific type

      if Ekind (Etype (N)) = E_Allocator_Type then
         Set_Etype (N, Base_Type (Typ));
      end if;

      if Is_Abstract_Type (Typ) then
         Error_Msg_N ("type of allocator cannot be abstract",  N);
      end if;

      --  For qualified expression, resolve the expression using the given
      --  subtype (nothing to do for type mark, subtype indication)

      if Nkind (E) = N_Qualified_Expression then
         if Is_Class_Wide_Type (Etype (E))
           and then not Is_Class_Wide_Type (Desig_T)
           and then not In_Dispatching_Context
         then
            Error_Msg_N
              ("class-wide allocator not allowed for this access type", N);
         end if;

         Resolve (Expression (E), Etype (E));
         Check_Non_Static_Context (Expression (E));
         Check_Unset_Reference (Expression (E));

         --  Allocators generated by the build-in-place expansion mechanism
         --  are explicitly marked as coming from source but do not need to be
         --  checked for limited initialization. To exclude this case, ensure
         --  that the parent of the allocator is a source node.
         --  The return statement constructed for an Expression_Function does
         --  not come from source but requires a limited check.

         if Is_Limited_Type (Etype (E))
           and then Comes_From_Source (N)
           and then
             (Comes_From_Source (Parent (N))
               or else
                 (Ekind (Current_Scope) = E_Function
                   and then Nkind (Original_Node (Unit_Declaration_Node
                              (Current_Scope))) = N_Expression_Function))
           and then not In_Instance_Body
         then
            if not OK_For_Limited_Init (Etype (E), Expression (E)) then
               if Nkind (Parent (N)) = N_Assignment_Statement then
                  Error_Msg_N
                    ("illegal expression for initialized allocator of a "
                     & "limited type (RM 7.5 (2.7/2))", N);
               else
                  Error_Msg_N
                    ("initialization not allowed for limited types", N);
               end if;

               Explain_Limited_Type (Etype (E), N);
            end if;
         end if;

         --  A qualified expression requires an exact match of the type. Class-
         --  wide matching is not allowed.

         if (Is_Class_Wide_Type (Etype (Expression (E)))
              or else Is_Class_Wide_Type (Etype (E)))
           and then Base_Type (Etype (Expression (E))) /= Base_Type (Etype (E))
         then
            Wrong_Type (Expression (E), Etype (E));
         end if;

         --  Calls to build-in-place functions are not currently supported in
         --  allocators for access types associated with a simple storage pool.
         --  Supporting such allocators may require passing additional implicit
         --  parameters to build-in-place functions (or a significant revision
         --  of the current b-i-p implementation to unify the handling for
         --  multiple kinds of storage pools). ???

         if Is_Limited_View (Desig_T)
           and then Nkind (Expression (E)) = N_Function_Call
         then
            declare
               Pool : constant Entity_Id :=
                        Associated_Storage_Pool (Root_Type (Typ));
            begin
               if Present (Pool)
                 and then
                   Present (Get_Rep_Pragma
                              (Etype (Pool), Name_Simple_Storage_Pool_Type))
               then
                  Error_Msg_N
                    ("limited function calls not yet supported in simple "
                     & "storage pool allocators", Expression (E));
               end if;
            end;
         end if;

         --  A special accessibility check is needed for allocators that
         --  constrain access discriminants. The level of the type of the
         --  expression used to constrain an access discriminant cannot be
         --  deeper than the type of the allocator (in contrast to access
         --  parameters, where the level of the actual can be arbitrary).

         --  We can't use Valid_Conversion to perform this check because in
         --  general the type of the allocator is unrelated to the type of
         --  the access discriminant.

         if Ekind (Typ) /= E_Anonymous_Access_Type
           or else Is_Local_Anonymous_Access (Typ)
         then
            Subtyp := Entity (Subtype_Mark (E));

            Aggr := Original_Node (Expression (E));

            if Has_Discriminants (Subtyp)
              and then Nkind_In (Aggr, N_Aggregate, N_Extension_Aggregate)
            then
               Discrim := First_Discriminant (Base_Type (Subtyp));

               --  Get the first component expression of the aggregate

               if Present (Expressions (Aggr)) then
                  Disc_Exp := First (Expressions (Aggr));

               elsif Present (Component_Associations (Aggr)) then
                  Assoc := First (Component_Associations (Aggr));

                  if Present (Assoc) then
                     Disc_Exp := Expression (Assoc);
                  else
                     Disc_Exp := Empty;
                  end if;

               else
                  Disc_Exp := Empty;
               end if;

               while Present (Discrim) and then Present (Disc_Exp) loop
                  if Ekind (Etype (Discrim)) = E_Anonymous_Access_Type then
                     Check_Allocator_Discrim_Accessibility_Exprs
                       (Disc_Exp, Typ);
                  end if;

                  Next_Discriminant (Discrim);

                  if Present (Discrim) then
                     if Present (Assoc) then
                        Next (Assoc);
                        Disc_Exp := Expression (Assoc);

                     elsif Present (Next (Disc_Exp)) then
                        Next (Disc_Exp);

                     else
                        Assoc := First (Component_Associations (Aggr));

                        if Present (Assoc) then
                           Disc_Exp := Expression (Assoc);
                        else
                           Disc_Exp := Empty;
                        end if;
                     end if;
                  end if;
               end loop;
            end if;
         end if;

      --  For a subtype mark or subtype indication, freeze the subtype

      else
         Freeze_Expression (E);

         if Is_Access_Constant (Typ) and then not No_Initialization (N) then
            Error_Msg_N
              ("initialization required for access-to-constant allocator", N);
         end if;

         --  A special accessibility check is needed for allocators that
         --  constrain access discriminants. The level of the type of the
         --  expression used to constrain an access discriminant cannot be
         --  deeper than the type of the allocator (in contrast to access
         --  parameters, where the level of the actual can be arbitrary).
         --  We can't use Valid_Conversion to perform this check because
         --  in general the type of the allocator is unrelated to the type
         --  of the access discriminant.

         if Nkind (Original_Node (E)) = N_Subtype_Indication
           and then (Ekind (Typ) /= E_Anonymous_Access_Type
                      or else Is_Local_Anonymous_Access (Typ))
         then
            Subtyp := Entity (Subtype_Mark (Original_Node (E)));

            if Has_Discriminants (Subtyp) then
               Discrim := First_Discriminant (Base_Type (Subtyp));
               Constr := First (Constraints (Constraint (Original_Node (E))));
               while Present (Discrim) and then Present (Constr) loop
                  if Ekind (Etype (Discrim)) = E_Anonymous_Access_Type then
                     if Nkind (Constr) = N_Discriminant_Association then
                        Disc_Exp := Expression (Constr);
                     else
                        Disc_Exp := Constr;
                     end if;

                     Check_Allocator_Discrim_Accessibility_Exprs
                       (Disc_Exp, Typ);
                  end if;

                  Next_Discriminant (Discrim);
                  Next (Constr);
               end loop;
            end if;
         end if;
      end if;

      --  Ada 2005 (AI-344): A class-wide allocator requires an accessibility
      --  check that the level of the type of the created object is not deeper
      --  than the level of the allocator's access type, since extensions can
      --  now occur at deeper levels than their ancestor types. This is a
      --  static accessibility level check; a run-time check is also needed in
      --  the case of an initialized allocator with a class-wide argument (see
      --  Expand_Allocator_Expression).

      if Ada_Version >= Ada_2005
        and then Is_Class_Wide_Type (Desig_T)
      then
         declare
            Exp_Typ : Entity_Id;

         begin
            if Nkind (E) = N_Qualified_Expression then
               Exp_Typ := Etype (E);
            elsif Nkind (E) = N_Subtype_Indication then
               Exp_Typ := Entity (Subtype_Mark (Original_Node (E)));
            else
               Exp_Typ := Entity (E);
            end if;

            if Type_Access_Level (Exp_Typ) >
                 Deepest_Type_Access_Level (Typ)
            then
               if In_Instance_Body then
                  Error_Msg_Warn := SPARK_Mode /= On;
                  Error_Msg_N
                    ("type in allocator has deeper level than designated "
                     & "class-wide type<<", E);
                  Error_Msg_N ("\Program_Error [<<", E);

                  Rewrite (N,
                    Make_Raise_Program_Error (Sloc (N),
                      Reason => PE_Accessibility_Check_Failed));
                  Set_Etype (N, Typ);

               --  Do not apply Ada 2005 accessibility checks on a class-wide
               --  allocator if the type given in the allocator is a formal
               --  type. A run-time check will be performed in the instance.

               elsif not Is_Generic_Type (Exp_Typ) then
                  Error_Msg_N
                    ("type in allocator has deeper level than designated "
                     & "class-wide type", E);
               end if;
            end if;
         end;
      end if;

      --  Check for allocation from an empty storage pool. But do not complain
      --  if it's a return statement for a build-in-place function, because the
      --  allocator is there just in case the caller uses an allocator. If the
      --  caller does use an allocator, it will be caught at the call site.

      if No_Pool_Assigned (Typ)
        and then not Alloc_For_BIP_Return (N)
      then
         Error_Msg_N ("allocation from empty storage pool!", N);

      --  If the context is an unchecked conversion, as may happen within an
      --  inlined subprogram, the allocator is being resolved with its own
      --  anonymous type. In that case, if the target type has a specific
      --  storage pool, it must be inherited explicitly by the allocator type.

      elsif Nkind (Parent (N)) = N_Unchecked_Type_Conversion
        and then No (Associated_Storage_Pool (Typ))
      then
         Set_Associated_Storage_Pool
           (Typ, Associated_Storage_Pool (Etype (Parent (N))));
      end if;

      if Ekind (Etype (N)) = E_Anonymous_Access_Type then
         Check_Restriction (No_Anonymous_Allocators, N);
      end if;

      --  Check that an allocator with task parts isn't for a nested access
      --  type when restriction No_Task_Hierarchy applies.

      if not Is_Library_Level_Entity (Base_Type (Typ))
        and then Has_Task (Base_Type (Desig_T))
      then
         Check_Restriction (No_Task_Hierarchy, N);
      end if;

      --  An illegal allocator may be rewritten as a raise Program_Error
      --  statement.

      if Nkind (N) = N_Allocator then

         --  Avoid coextension processing for an allocator that is the
         --  expansion of a build-in-place function call.

         if Nkind (Original_Node (N)) = N_Allocator
           and then Nkind (Expression (Original_Node (N))) =
                      N_Qualified_Expression
           and then Nkind (Expression (Expression (Original_Node (N)))) =
                      N_Function_Call
           and then Is_Expanded_Build_In_Place_Call
                      (Expression (Expression (Original_Node (N))))
         then
            null; -- b-i-p function call case

         else
            --  An anonymous access discriminant is the definition of a
            --  coextension.

            if Ekind (Typ) = E_Anonymous_Access_Type
              and then Nkind (Associated_Node_For_Itype (Typ)) =
                         N_Discriminant_Specification
            then
               declare
                  Discr : constant Entity_Id :=
                    Defining_Identifier (Associated_Node_For_Itype (Typ));

               begin
                  Check_Restriction (No_Coextensions, N);

                  --  Ada 2012 AI05-0052: If the designated type of the
                  --  allocator is limited, then the allocator shall not
                  --  be used to define the value of an access discriminant
                  --  unless the discriminated type is immutably limited.

                  if Ada_Version >= Ada_2012
                    and then Is_Limited_Type (Desig_T)
                    and then not Is_Limited_View (Scope (Discr))
                  then
                     Error_Msg_N
                       ("only immutably limited types can have anonymous "
                        & "access discriminants designating a limited type",
                        N);
                  end if;
               end;

               --  Avoid marking an allocator as a dynamic coextension if it is
               --  within a static construct.

               if not Is_Static_Coextension (N) then
                  Set_Is_Dynamic_Coextension (N);

                  --  Finalization and deallocation of coextensions utilizes an
                  --  approximate implementation which does not directly adhere
                  --  to the semantic rules. Warn on potential issues involving
                  --  coextensions.

                  if Is_Controlled (Desig_T) then
                     Error_Msg_N
                       ("??coextension will not be finalized when its "
                        & "associated owner is deallocated or finalized", N);
                  else
                     Error_Msg_N
                       ("??coextension will not be deallocated when its "
                        & "associated owner is deallocated", N);
                  end if;
               end if;

            --  Cleanup for potential static coextensions

            else
               Set_Is_Dynamic_Coextension (N, False);
               Set_Is_Static_Coextension  (N, False);

               --  Anonymous access-to-controlled objects are not finalized on
               --  time because this involves run-time ownership and currently
               --  this property is not available. In rare cases the object may
               --  not be finalized at all. Warn on potential issues involving
               --  anonymous access-to-controlled objects.

               if Ekind (Typ) = E_Anonymous_Access_Type
                 and then Is_Controlled_Active (Desig_T)
               then
                  Error_Msg_N
                    ("??object designated by anonymous access object might "
                     & "not be finalized until its enclosing library unit "
                     & "goes out of scope", N);
                  Error_Msg_N ("\use named access type instead", N);
               end if;
            end if;
         end if;
      end if;

      --  Report a simple error: if the designated object is a local task,
      --  its body has not been seen yet, and its activation will fail an
      --  elaboration check.

      if Is_Task_Type (Desig_T)
        and then Scope (Base_Type (Desig_T)) = Current_Scope
        and then Is_Compilation_Unit (Current_Scope)
        and then Ekind (Current_Scope) = E_Package
        and then not In_Package_Body (Current_Scope)
      then
         Error_Msg_Warn := SPARK_Mode /= On;
         Error_Msg_N ("cannot activate task before body seen<<", N);
         Error_Msg_N ("\Program_Error [<<", N);
      end if;

      --  Ada 2012 (AI05-0111-3): Detect an attempt to allocate a task or a
      --  type with a task component on a subpool. This action must raise
      --  Program_Error at runtime.

      if Ada_Version >= Ada_2012
        and then Nkind (N) = N_Allocator
        and then Present (Subpool_Handle_Name (N))
        and then Has_Task (Desig_T)
      then
         Error_Msg_Warn := SPARK_Mode /= On;
         Error_Msg_N ("cannot allocate task on subpool<<", N);
         Error_Msg_N ("\Program_Error [<<", N);

         Rewrite (N,
           Make_Raise_Program_Error (Sloc (N),
             Reason => PE_Explicit_Raise));
         Set_Etype (N, Typ);
      end if;
   end Resolve_Allocator;

   ---------------------------
   -- Resolve_Arithmetic_Op --
   ---------------------------

   --  Used for resolving all arithmetic operators except exponentiation

   procedure Resolve_Arithmetic_Op (N : Node_Id; Typ : Entity_Id) is
      L   : constant Node_Id := Left_Opnd (N);
      R   : constant Node_Id := Right_Opnd (N);
      TL  : constant Entity_Id := Base_Type (Etype (L));
      TR  : constant Entity_Id := Base_Type (Etype (R));
      T   : Entity_Id;
      Rop : Node_Id;

      B_Typ : constant Entity_Id := Base_Type (Typ);
      --  We do the resolution using the base type, because intermediate values
      --  in expressions always are of the base type, not a subtype of it.

      function Expected_Type_Is_Any_Real (N : Node_Id) return Boolean;
      --  Returns True if N is in a context that expects "any real type"

      function Is_Integer_Or_Universal (N : Node_Id) return Boolean;
      --  Return True iff given type is Integer or universal real/integer

      procedure Set_Mixed_Mode_Operand (N : Node_Id; T : Entity_Id);
      --  Choose type of integer literal in fixed-point operation to conform
      --  to available fixed-point type. T is the type of the other operand,
      --  which is needed to determine the expected type of N.

      procedure Set_Operand_Type (N : Node_Id);
      --  Set operand type to T if universal

      -------------------------------
      -- Expected_Type_Is_Any_Real --
      -------------------------------

      function Expected_Type_Is_Any_Real (N : Node_Id) return Boolean is
      begin
         --  N is the expression after "delta" in a fixed_point_definition;
         --  see RM-3.5.9(6):

         return Nkind_In (Parent (N), N_Ordinary_Fixed_Point_Definition,
                                      N_Decimal_Fixed_Point_Definition,

         --  N is one of the bounds in a real_range_specification;
         --  see RM-3.5.7(5):

                                      N_Real_Range_Specification,

         --  N is the expression of a delta_constraint;
         --  see RM-J.3(3):

                                      N_Delta_Constraint);
      end Expected_Type_Is_Any_Real;

      -----------------------------
      -- Is_Integer_Or_Universal --
      -----------------------------

      function Is_Integer_Or_Universal (N : Node_Id) return Boolean is
         T     : Entity_Id;
         Index : Interp_Index;
         It    : Interp;

      begin
         if not Is_Overloaded (N) then
            T := Etype (N);
            return Base_Type (T) = Base_Type (Standard_Integer)
              or else T = Universal_Integer
              or else T = Universal_Real;
         else
            Get_First_Interp (N, Index, It);
            while Present (It.Typ) loop
               if Base_Type (It.Typ) = Base_Type (Standard_Integer)
                 or else It.Typ = Universal_Integer
                 or else It.Typ = Universal_Real
               then
                  return True;
               end if;

               Get_Next_Interp (Index, It);
            end loop;
         end if;

         return False;
      end Is_Integer_Or_Universal;

      ----------------------------
      -- Set_Mixed_Mode_Operand --
      ----------------------------

      procedure Set_Mixed_Mode_Operand (N : Node_Id; T : Entity_Id) is
         Index : Interp_Index;
         It    : Interp;

      begin
         if Universal_Interpretation (N) = Universal_Integer then

            --  A universal integer literal is resolved as standard integer
            --  except in the case of a fixed-point result, where we leave it
            --  as universal (to be handled by Exp_Fixd later on)

            if Is_Fixed_Point_Type (T) then
               Resolve (N, Universal_Integer);
            else
               Resolve (N, Standard_Integer);
            end if;

         elsif Universal_Interpretation (N) = Universal_Real
           and then (T = Base_Type (Standard_Integer)
                      or else T = Universal_Integer
                      or else T = Universal_Real)
         then
            --  A universal real can appear in a fixed-type context. We resolve
            --  the literal with that context, even though this might raise an
            --  exception prematurely (the other operand may be zero).

            Resolve (N, B_Typ);

         elsif Etype (N) = Base_Type (Standard_Integer)
           and then T = Universal_Real
           and then Is_Overloaded (N)
         then
            --  Integer arg in mixed-mode operation. Resolve with universal
            --  type, in case preference rule must be applied.

            Resolve (N, Universal_Integer);

         elsif Etype (N) = T and then B_Typ /= Universal_Fixed then

            --  If the operand is part of a fixed multiplication operation,
            --  a conversion will be applied to each operand, so resolve it
            --  with its own type.

            if Nkind_In (Parent (N), N_Op_Divide, N_Op_Multiply) then
               Resolve (N);

            else
               --  Not a mixed-mode operation, resolve with context

               Resolve (N, B_Typ);
            end if;

         elsif Etype (N) = Any_Fixed then

            --  N may itself be a mixed-mode operation, so use context type

            Resolve (N, B_Typ);

         elsif Is_Fixed_Point_Type (T)
           and then B_Typ = Universal_Fixed
           and then Is_Overloaded (N)
         then
            --  Must be (fixed * fixed) operation, operand must have one
            --  compatible interpretation.

            Resolve (N, Any_Fixed);

         elsif Is_Fixed_Point_Type (B_Typ)
           and then (T = Universal_Real or else Is_Fixed_Point_Type (T))
           and then Is_Overloaded (N)
         then
            --  C * F(X) in a fixed context, where C is a real literal or a
            --  fixed-point expression. F must have either a fixed type
            --  interpretation or an integer interpretation, but not both.

            Get_First_Interp (N, Index, It);
            while Present (It.Typ) loop
               if Base_Type (It.Typ) = Base_Type (Standard_Integer) then
                  if Analyzed (N) then
                     Error_Msg_N ("ambiguous operand in fixed operation", N);
                  else
                     Resolve (N, Standard_Integer);
                  end if;

               elsif Is_Fixed_Point_Type (It.Typ) then
                  if Analyzed (N) then
                     Error_Msg_N ("ambiguous operand in fixed operation", N);
                  else
                     Resolve (N, It.Typ);
                  end if;
               end if;

               Get_Next_Interp (Index, It);
            end loop;

            --  Reanalyze the literal with the fixed type of the context. If
            --  context is Universal_Fixed, we are within a conversion, leave
            --  the literal as a universal real because there is no usable
            --  fixed type, and the target of the conversion plays no role in
            --  the resolution.

            declare
               Op2 : Node_Id;
               T2  : Entity_Id;

            begin
               if N = L then
                  Op2 := R;
               else
                  Op2 := L;
               end if;

               if B_Typ = Universal_Fixed
                  and then Nkind (Op2) = N_Real_Literal
               then
                  T2 := Universal_Real;
               else
                  T2 := B_Typ;
               end if;

               Set_Analyzed (Op2, False);
               Resolve (Op2, T2);
            end;

         --  A universal real conditional expression can appear in a fixed-type
         --  context and must be resolved with that context to facilitate the
         --  code generation in the back end. However, If the context is
         --  Universal_fixed (i.e. as an operand of a multiplication/division
         --  involving a fixed-point operand) the conditional expression must
         --  resolve to a unique visible fixed_point type, normally Duration.

         elsif Nkind_In (N, N_Case_Expression, N_If_Expression)
           and then Etype (N) = Universal_Real
           and then Is_Fixed_Point_Type (B_Typ)
         then
            if B_Typ = Universal_Fixed then
               Resolve (N, Unique_Fixed_Point_Type (N));

            else
               Resolve (N, B_Typ);
            end if;

         else
            Resolve (N);
         end if;
      end Set_Mixed_Mode_Operand;

      ----------------------
      -- Set_Operand_Type --
      ----------------------

      procedure Set_Operand_Type (N : Node_Id) is
      begin
         if Etype (N) = Universal_Integer
           or else Etype (N) = Universal_Real
         then
            Set_Etype (N, T);
         end if;
      end Set_Operand_Type;

   --  Start of processing for Resolve_Arithmetic_Op

   begin
      if Comes_From_Source (N)
        and then Ekind (Entity (N)) = E_Function
        and then Is_Imported (Entity (N))
        and then Is_Intrinsic_Subprogram (Entity (N))
      then
         Resolve_Intrinsic_Operator (N, Typ);
         return;

      --  Special-case for mixed-mode universal expressions or fixed point type
      --  operation: each argument is resolved separately. The same treatment
      --  is required if one of the operands of a fixed point operation is
      --  universal real, since in this case we don't do a conversion to a
      --  specific fixed-point type (instead the expander handles the case).

      --  Set the type of the node to its universal interpretation because
      --  legality checks on an exponentiation operand need the context.

      elsif (B_Typ = Universal_Integer or else B_Typ = Universal_Real)
        and then Present (Universal_Interpretation (L))
        and then Present (Universal_Interpretation (R))
      then
         Set_Etype (N, B_Typ);
         Resolve (L, Universal_Interpretation (L));
         Resolve (R, Universal_Interpretation (R));

      elsif (B_Typ = Universal_Real
              or else Etype (N) = Universal_Fixed
              or else (Etype (N) = Any_Fixed
                        and then Is_Fixed_Point_Type (B_Typ))
              or else (Is_Fixed_Point_Type (B_Typ)
                        and then (Is_Integer_Or_Universal (L)
                                    or else
                                  Is_Integer_Or_Universal (R))))
        and then Nkind_In (N, N_Op_Multiply, N_Op_Divide)
      then
         if TL = Universal_Integer or else TR = Universal_Integer then
            Check_For_Visible_Operator (N, B_Typ);
         end if;

         --  If context is a fixed type and one operand is integer, the other
         --  is resolved with the type of the context.

         if Is_Fixed_Point_Type (B_Typ)
           and then (Base_Type (TL) = Base_Type (Standard_Integer)
                      or else TL = Universal_Integer)
         then
            Resolve (R, B_Typ);
            Resolve (L, TL);

         elsif Is_Fixed_Point_Type (B_Typ)
           and then (Base_Type (TR) = Base_Type (Standard_Integer)
                      or else TR = Universal_Integer)
         then
            Resolve (L, B_Typ);
            Resolve (R, TR);

         --  If both operands are universal and the context is a floating
         --  point type, the operands are resolved to the type of the context.

         elsif Is_Floating_Point_Type (B_Typ) then
            Resolve (L, B_Typ);
            Resolve (R, B_Typ);

         else
            Set_Mixed_Mode_Operand (L, TR);
            Set_Mixed_Mode_Operand (R, TL);
         end if;

         --  Check the rule in RM05-4.5.5(19.1/2) disallowing universal_fixed
         --  multiplying operators from being used when the expected type is
         --  also universal_fixed. Note that B_Typ will be Universal_Fixed in
         --  some cases where the expected type is actually Any_Real;
         --  Expected_Type_Is_Any_Real takes care of that case.

         if Etype (N) = Universal_Fixed
           or else Etype (N) = Any_Fixed
         then
            if B_Typ = Universal_Fixed
              and then not Expected_Type_Is_Any_Real (N)
              and then not Nkind_In (Parent (N), N_Type_Conversion,
                                                 N_Unchecked_Type_Conversion)
            then
               Error_Msg_N ("type cannot be determined from context!", N);
               Error_Msg_N ("\explicit conversion to result type required", N);

               Set_Etype (L, Any_Type);
               Set_Etype (R, Any_Type);

            else
               if Ada_Version = Ada_83
                 and then Etype (N) = Universal_Fixed
                 and then not
                   Nkind_In (Parent (N), N_Type_Conversion,
                                         N_Unchecked_Type_Conversion)
               then
                  Error_Msg_N
                    ("(Ada 83) fixed-point operation needs explicit "
                     & "conversion", N);
               end if;

               --  The expected type is "any real type" in contexts like

               --    type T is delta <universal_fixed-expression> ...

               --  in which case we need to set the type to Universal_Real
               --  so that static expression evaluation will work properly.

               if Expected_Type_Is_Any_Real (N) then
                  Set_Etype (N, Universal_Real);
               else
                  Set_Etype (N, B_Typ);
               end if;
            end if;

         elsif Is_Fixed_Point_Type (B_Typ)
           and then (Is_Integer_Or_Universal (L)
                       or else Nkind (L) = N_Real_Literal
                       or else Nkind (R) = N_Real_Literal
                       or else Is_Integer_Or_Universal (R))
         then
            Set_Etype (N, B_Typ);

         elsif Etype (N) = Any_Fixed then

            --  If no previous errors, this is only possible if one operand is
            --  overloaded and the context is universal. Resolve as such.

            Set_Etype (N, B_Typ);
         end if;

      else
         if (TL = Universal_Integer or else TL = Universal_Real)
               and then
            (TR = Universal_Integer or else TR = Universal_Real)
         then
            Check_For_Visible_Operator (N, B_Typ);
         end if;

         --  If the context is Universal_Fixed and the operands are also
         --  universal fixed, this is an error, unless there is only one
         --  applicable fixed_point type (usually Duration).

         if B_Typ = Universal_Fixed and then Etype (L) = Universal_Fixed then
            T := Unique_Fixed_Point_Type (N);

            if T  = Any_Type then
               Set_Etype (N, T);
               return;
            else
               Resolve (L, T);
               Resolve (R, T);
            end if;

         else
            Resolve (L, B_Typ);
            Resolve (R, B_Typ);
         end if;

         --  If one of the arguments was resolved to a non-universal type.
         --  label the result of the operation itself with the same type.
         --  Do the same for the universal argument, if any.

         T := Intersect_Types (L, R);
         Set_Etype (N, Base_Type (T));
         Set_Operand_Type (L);
         Set_Operand_Type (R);
      end if;

      Generate_Operator_Reference (N, Typ);
      Analyze_Dimension (N);
      Eval_Arithmetic_Op (N);

      --  In SPARK, a multiplication or division with operands of fixed point
      --  types must be qualified or explicitly converted to identify the
      --  result type.

      if (Is_Fixed_Point_Type (Etype (L))
           or else Is_Fixed_Point_Type (Etype (R)))
        and then Nkind_In (N, N_Op_Multiply, N_Op_Divide)
        and then
          not Nkind_In (Parent (N), N_Qualified_Expression, N_Type_Conversion)
      then
         Check_SPARK_05_Restriction
           ("operation should be qualified or explicitly converted", N);
      end if;

      --  Set overflow and division checking bit

      if Nkind (N) in N_Op then
         if not Overflow_Checks_Suppressed (Etype (N)) then
            Enable_Overflow_Check (N);
         end if;

         --  Give warning if explicit division by zero

         if Nkind_In (N, N_Op_Divide, N_Op_Rem, N_Op_Mod)
           and then not Division_Checks_Suppressed (Etype (N))
         then
            Rop := Right_Opnd (N);

            if Compile_Time_Known_Value (Rop)
              and then ((Is_Integer_Type (Etype (Rop))
                          and then Expr_Value (Rop) = Uint_0)
                         or else
                           (Is_Real_Type (Etype (Rop))
                             and then Expr_Value_R (Rop) = Ureal_0))
            then
               --  Specialize the warning message according to the operation.
               --  When SPARK_Mode is On, force a warning instead of an error
               --  in that case, as this likely corresponds to deactivated
               --  code. The following warnings are for the case

               case Nkind (N) is
                  when N_Op_Divide =>

                     --  For division, we have two cases, for float division
                     --  of an unconstrained float type, on a machine where
                     --  Machine_Overflows is false, we don't get an exception
                     --  at run-time, but rather an infinity or Nan. The Nan
                     --  case is pretty obscure, so just warn about infinities.

                     if Is_Floating_Point_Type (Typ)
                       and then not Is_Constrained (Typ)
                       and then not Machine_Overflows_On_Target
                     then
                        Error_Msg_N
                          ("float division by zero, may generate "
                           & "'+'/'- infinity??", Right_Opnd (N));

                     --  For all other cases, we get a Constraint_Error

                     else
                        Apply_Compile_Time_Constraint_Error
                          (N, "division by zero??", CE_Divide_By_Zero,
                           Loc  => Sloc (Right_Opnd (N)),
                           Warn => SPARK_Mode = On);
                     end if;

                  when N_Op_Rem =>
                     Apply_Compile_Time_Constraint_Error
                       (N, "rem with zero divisor??", CE_Divide_By_Zero,
                        Loc  => Sloc (Right_Opnd (N)),
                        Warn => SPARK_Mode = On);

                  when N_Op_Mod =>
                     Apply_Compile_Time_Constraint_Error
                       (N, "mod with zero divisor??", CE_Divide_By_Zero,
                        Loc  => Sloc (Right_Opnd (N)),
                        Warn => SPARK_Mode = On);

                  --  Division by zero can only happen with division, rem,
                  --  and mod operations.

                  when others =>
                     raise Program_Error;
               end case;

               --  In GNATprove mode, we enable the division check so that
               --  GNATprove will issue a message if it cannot be proved.

               if GNATprove_Mode then
                  Activate_Division_Check (N);
               end if;

            --  Otherwise just set the flag to check at run time

            else
               Activate_Division_Check (N);
            end if;
         end if;

         --  If Restriction No_Implicit_Conditionals is active, then it is
         --  violated if either operand can be negative for mod, or for rem
         --  if both operands can be negative.

         if Restriction_Check_Required (No_Implicit_Conditionals)
           and then Nkind_In (N, N_Op_Rem, N_Op_Mod)
         then
            declare
               Lo : Uint;
               Hi : Uint;
               OK : Boolean;

               LNeg : Boolean;
               RNeg : Boolean;
               --  Set if corresponding operand might be negative

            begin
               Determine_Range
                 (Left_Opnd (N), OK, Lo, Hi, Assume_Valid => True);
               LNeg := (not OK) or else Lo < 0;

               Determine_Range
                 (Right_Opnd (N), OK, Lo, Hi, Assume_Valid => True);
               RNeg := (not OK) or else Lo < 0;

               --  Check if we will be generating conditionals. There are two
               --  cases where that can happen, first for REM, the only case
               --  is largest negative integer mod -1, where the division can
               --  overflow, but we still have to give the right result. The
               --  front end generates a test for this annoying case. Here we
               --  just test if both operands can be negative (that's what the
               --  expander does, so we match its logic here).

               --  The second case is mod where either operand can be negative.
               --  In this case, the back end has to generate additional tests.

               if (Nkind (N) = N_Op_Rem and then (LNeg and RNeg))
                     or else
                  (Nkind (N) = N_Op_Mod and then (LNeg or RNeg))
               then
                  Check_Restriction (No_Implicit_Conditionals, N);
               end if;
            end;
         end if;
      end if;

      Check_Unset_Reference (L);
      Check_Unset_Reference (R);
   end Resolve_Arithmetic_Op;

   ------------------
   -- Resolve_Call --
   ------------------

   procedure Resolve_Call (N : Node_Id; Typ : Entity_Id) is
      function Same_Or_Aliased_Subprograms
        (S : Entity_Id;
         E : Entity_Id) return Boolean;
      --  Returns True if the subprogram entity S is the same as E or else
      --  S is an alias of E.

      ---------------------------------
      -- Same_Or_Aliased_Subprograms --
      ---------------------------------

      function Same_Or_Aliased_Subprograms
        (S : Entity_Id;
         E : Entity_Id) return Boolean
      is
         Subp_Alias : constant Entity_Id := Alias (S);
      begin
         return S = E or else (Present (Subp_Alias) and then Subp_Alias = E);
      end Same_Or_Aliased_Subprograms;

      --  Local variables

      Loc      : constant Source_Ptr := Sloc (N);
      Subp     : constant Node_Id    := Name (N);
      Body_Id  : Entity_Id;
      I        : Interp_Index;
      It       : Interp;
      Nam      : Entity_Id;
      Nam_Decl : Node_Id;
      Nam_UA   : Entity_Id;
      Norm_OK  : Boolean;
      Rtype    : Entity_Id;
      Scop     : Entity_Id;

   --  Start of processing for Resolve_Call

   begin
      --  Preserve relevant elaboration-related attributes of the context which
      --  are no longer available or very expensive to recompute once analysis,
      --  resolution, and expansion are over.

      Mark_Elaboration_Attributes
        (N_Id     => N,
         Checks   => True,
         Modes    => True,
         Warnings => True);

      --  The context imposes a unique interpretation with type Typ on a
      --  procedure or function call. Find the entity of the subprogram that
      --  yields the expected type, and propagate the corresponding formal
      --  constraints on the actuals. The caller has established that an
      --  interpretation exists, and emitted an error if not unique.

      --  First deal with the case of a call to an access-to-subprogram,
      --  dereference made explicit in Analyze_Call.

      if Ekind (Etype (Subp)) = E_Subprogram_Type then
         if not Is_Overloaded (Subp) then
            Nam := Etype (Subp);

         else
            --  Find the interpretation whose type (a subprogram type) has a
            --  return type that is compatible with the context. Analysis of
            --  the node has established that one exists.

            Nam := Empty;

            Get_First_Interp (Subp,  I, It);
            while Present (It.Typ) loop
               if Covers (Typ, Etype (It.Typ)) then
                  Nam := It.Typ;
                  exit;
               end if;

               Get_Next_Interp (I, It);
            end loop;

            if No (Nam) then
               raise Program_Error;
            end if;
         end if;

         --  If the prefix is not an entity, then resolve it

         if not Is_Entity_Name (Subp) then
            Resolve (Subp, Nam);
         end if;

         --  For an indirect call, we always invalidate checks, since we do not
         --  know whether the subprogram is local or global. Yes we could do
         --  better here, e.g. by knowing that there are no local subprograms,
         --  but it does not seem worth the effort. Similarly, we kill all
         --  knowledge of current constant values.

         Kill_Current_Values;

      --  If this is a procedure call which is really an entry call, do
      --  the conversion of the procedure call to an entry call. Protected
      --  operations use the same circuitry because the name in the call
      --  can be an arbitrary expression with special resolution rules.

      elsif Nkind_In (Subp, N_Selected_Component, N_Indexed_Component)
        or else (Is_Entity_Name (Subp)
                  and then Ekind_In (Entity (Subp), E_Entry, E_Entry_Family))
      then
         Resolve_Entry_Call (N, Typ);

         if Legacy_Elaboration_Checks then
            Check_Elab_Call (N);
         end if;

         --  Annotate the tree by creating a call marker in case the original
         --  call is transformed by expansion. The call marker is automatically
         --  saved for later examination by the ABE Processing phase.

         Build_Call_Marker (N);

         --  Kill checks and constant values, as above for indirect case
         --  Who knows what happens when another task is activated?

         Kill_Current_Values;
         return;

      --  Normal subprogram call with name established in Resolve

      elsif not (Is_Type (Entity (Subp))) then
         Nam := Entity (Subp);
         Set_Entity_With_Checks (Subp, Nam);

      --  Otherwise we must have the case of an overloaded call

      else
         pragma Assert (Is_Overloaded (Subp));

         --  Initialize Nam to prevent warning (we know it will be assigned
         --  in the loop below, but the compiler does not know that).

         Nam := Empty;

         Get_First_Interp (Subp,  I, It);
         while Present (It.Typ) loop
            if Covers (Typ, It.Typ) then
               Nam := It.Nam;
               Set_Entity_With_Checks (Subp, Nam);
               exit;
            end if;

            Get_Next_Interp (I, It);
         end loop;
      end if;

      if Is_Access_Subprogram_Type (Base_Type (Etype (Nam)))
        and then not Is_Access_Subprogram_Type (Base_Type (Typ))
        and then Nkind (Subp) /= N_Explicit_Dereference
        and then Present (Parameter_Associations (N))
      then
         --  The prefix is a parameterless function call that returns an access
         --  to subprogram. If parameters are present in the current call, add
         --  add an explicit dereference. We use the base type here because
         --  within an instance these may be subtypes.

         --  The dereference is added either in Analyze_Call or here. Should
         --  be consolidated ???

         Set_Is_Overloaded (Subp, False);
         Set_Etype (Subp, Etype (Nam));
         Insert_Explicit_Dereference (Subp);
         Nam := Designated_Type (Etype (Nam));
         Resolve (Subp, Nam);
      end if;

      --  Check that a call to Current_Task does not occur in an entry body

      if Is_RTE (Nam, RE_Current_Task) then
         declare
            P : Node_Id;

         begin
            P := N;
            loop
               P := Parent (P);

               --  Exclude calls that occur within the default of a formal
               --  parameter of the entry, since those are evaluated outside
               --  of the body.

               exit when No (P) or else Nkind (P) = N_Parameter_Specification;

               if Nkind (P) = N_Entry_Body
                 or else (Nkind (P) = N_Subprogram_Body
                           and then Is_Entry_Barrier_Function (P))
               then
                  Rtype := Etype (N);
                  Error_Msg_Warn := SPARK_Mode /= On;
                  Error_Msg_NE
                    ("& should not be used in entry body (RM C.7(17))<<",
                     N, Nam);
                  Error_Msg_NE ("\Program_Error [<<", N, Nam);
                  Rewrite (N,
                    Make_Raise_Program_Error (Loc,
                      Reason => PE_Current_Task_In_Entry_Body));
                  Set_Etype (N, Rtype);
                  return;
               end if;
            end loop;
         end;
      end if;

      --  Check that a procedure call does not occur in the context of the
      --  entry call statement of a conditional or timed entry call. Note that
      --  the case of a call to a subprogram renaming of an entry will also be
      --  rejected. The test for N not being an N_Entry_Call_Statement is
      --  defensive, covering the possibility that the processing of entry
      --  calls might reach this point due to later modifications of the code
      --  above.

      if Nkind (Parent (N)) = N_Entry_Call_Alternative
        and then Nkind (N) /= N_Entry_Call_Statement
        and then Entry_Call_Statement (Parent (N)) = N
      then
         if Ada_Version < Ada_2005 then
            Error_Msg_N ("entry call required in select statement", N);

         --  Ada 2005 (AI-345): If a procedure_call_statement is used
         --  for a procedure_or_entry_call, the procedure_name or
         --  procedure_prefix of the procedure_call_statement shall denote
         --  an entry renamed by a procedure, or (a view of) a primitive
         --  subprogram of a limited interface whose first parameter is
         --  a controlling parameter.

         elsif Nkind (N) = N_Procedure_Call_Statement
           and then not Is_Renamed_Entry (Nam)
           and then not Is_Controlling_Limited_Procedure (Nam)
         then
            Error_Msg_N
             ("entry call or dispatching primitive of interface required", N);
         end if;
      end if;

      --  If the SPARK_05 restriction is active, we are not allowed
      --  to have a call to a subprogram before we see its completion.

      if not Has_Completion (Nam)
        and then Restriction_Check_Required (SPARK_05)

        --  Don't flag strange internal calls

        and then Comes_From_Source (N)
        and then Comes_From_Source (Nam)

        --  Only flag calls in extended main source

        and then In_Extended_Main_Source_Unit (Nam)
        and then In_Extended_Main_Source_Unit (N)

        --  Exclude enumeration literals from this processing

        and then Ekind (Nam) /= E_Enumeration_Literal
      then
         Check_SPARK_05_Restriction
           ("call to subprogram cannot appear before its body", N);
      end if;

      --  Check that this is not a call to a protected procedure or entry from
      --  within a protected function.

      Check_Internal_Protected_Use (N, Nam);

      --  Freeze the subprogram name if not in a spec-expression. Note that
      --  we freeze procedure calls as well as function calls. Procedure calls
      --  are not frozen according to the rules (RM 13.14(14)) because it is
      --  impossible to have a procedure call to a non-frozen procedure in
      --  pure Ada, but in the code that we generate in the expander, this
      --  rule needs extending because we can generate procedure calls that
      --  need freezing.

      --  In Ada 2012, expression functions may be called within pre/post
      --  conditions of subsequent functions or expression functions. Such
      --  calls do not freeze when they appear within generated bodies,
      --  (including the body of another expression function) which would
      --  place the freeze node in the wrong scope. An expression function
      --  is frozen in the usual fashion, by the appearance of a real body,
      --  or at the end of a declarative part. However an implicit call to
      --  an expression function may appear when it is part of a default
      --  expression in a call to an initialization procedure, and must be
      --  frozen now, even if the body is inserted at a later point.
      --  Otherwise, the call freezes the expression if expander is active,
      --  for example as part of an object declaration.

      if Is_Entity_Name (Subp)
        and then not In_Spec_Expression
        and then not Is_Expression_Function_Or_Completion (Current_Scope)
        and then
          (not Is_Expression_Function_Or_Completion (Entity (Subp))
            or else Expander_Active)
      then
         if Is_Expression_Function (Entity (Subp)) then

            --  Force freeze of expression function in call

            Set_Comes_From_Source (Subp, True);
            Set_Must_Not_Freeze   (Subp, False);
         end if;

         Freeze_Expression (Subp);
      end if;

      --  For a predefined operator, the type of the result is the type imposed
      --  by context, except for a predefined operation on universal fixed.
      --  Otherwise the type of the call is the type returned by the subprogram
      --  being called.

      if Is_Predefined_Op (Nam) then
         if Etype (N) /= Universal_Fixed then
            Set_Etype (N, Typ);
         end if;

      --  If the subprogram returns an array type, and the context requires the
      --  component type of that array type, the node is really an indexing of
      --  the parameterless call. Resolve as such. A pathological case occurs
      --  when the type of the component is an access to the array type. In
      --  this case the call is truly ambiguous. If the call is to an intrinsic
      --  subprogram, it can't be an indexed component. This check is necessary
      --  because if it's Unchecked_Conversion, and we have "type T_Ptr is
      --  access T;" and "type T is array (...) of T_Ptr;" (i.e. an array of
      --  pointers to the same array), the compiler gets confused and does an
      --  infinite recursion.

      elsif (Needs_No_Actuals (Nam) or else Needs_One_Actual (Nam))
        and then
          ((Is_Array_Type (Etype (Nam))
             and then Covers (Typ, Component_Type (Etype (Nam))))
           or else
             (Is_Access_Type (Etype (Nam))
               and then Is_Array_Type (Designated_Type (Etype (Nam)))
               and then
                 Covers (Typ, Component_Type (Designated_Type (Etype (Nam))))
               and then not Is_Intrinsic_Subprogram (Entity (Subp))))
      then
         declare
            Index_Node : Node_Id;
            New_Subp   : Node_Id;
            Ret_Type   : constant Entity_Id := Etype (Nam);

         begin
            --  If this is a parameterless call there is no ambiguity and the
            --  call has the type of the function.

            if No (First_Actual (N)) then
               Set_Etype (N, Etype (Nam));

               if Present (First_Formal (Nam)) then
                  Resolve_Actuals (N, Nam);
               end if;

               --  Annotate the tree by creating a call marker in case the
               --  original call is transformed by expansion. The call marker
               --  is automatically saved for later examination by the ABE
               --  Processing phase.

               Build_Call_Marker (N);

            elsif Is_Access_Type (Ret_Type)

              and then Ret_Type = Component_Type (Designated_Type (Ret_Type))
            then
               Error_Msg_N
                 ("cannot disambiguate function call and indexing", N);
            else
               New_Subp := Relocate_Node (Subp);

               --  The called entity may be an explicit dereference, in which
               --  case there is no entity to set.

               if Nkind (New_Subp) /= N_Explicit_Dereference then
                  Set_Entity (Subp, Nam);
               end if;

               if (Is_Array_Type (Ret_Type)
                    and then Component_Type (Ret_Type) /= Any_Type)
                 or else
                  (Is_Access_Type (Ret_Type)
                    and then
                      Component_Type (Designated_Type (Ret_Type)) /= Any_Type)
               then
                  if Needs_No_Actuals (Nam) then

                     --  Indexed call to a parameterless function

                     Index_Node :=
                       Make_Indexed_Component (Loc,
                         Prefix      =>
                           Make_Function_Call (Loc, Name => New_Subp),
                         Expressions => Parameter_Associations (N));
                  else
                     --  An Ada 2005 prefixed call to a primitive operation
                     --  whose first parameter is the prefix. This prefix was
                     --  prepended to the parameter list, which is actually a
                     --  list of indexes. Remove the prefix in order to build
                     --  the proper indexed component.

                     Index_Node :=
                       Make_Indexed_Component (Loc,
                         Prefix      =>
                           Make_Function_Call (Loc,
                             Name                   => New_Subp,
                             Parameter_Associations =>
                               New_List
                                 (Remove_Head (Parameter_Associations (N)))),
                         Expressions => Parameter_Associations (N));
                  end if;

                  --  Preserve the parenthesis count of the node

                  Set_Paren_Count (Index_Node, Paren_Count (N));

                  --  Since we are correcting a node classification error made
                  --  by the parser, we call Replace rather than Rewrite.

                  Replace (N, Index_Node);

                  Set_Etype (Prefix (N), Ret_Type);
                  Set_Etype (N, Typ);
                  Resolve_Indexed_Component (N, Typ);

                  if Legacy_Elaboration_Checks then
                     Check_Elab_Call (Prefix (N));
                  end if;

                  --  Annotate the tree by creating a call marker in case
                  --  the original call is transformed by expansion. The call
                  --  marker is automatically saved for later examination by
                  --  the ABE Processing phase.

                  Build_Call_Marker (Prefix (N));
               end if;
            end if;

            return;
         end;

      else
         --  If the called function is not declared in the main unit and it
         --  returns the limited view of type then use the available view (as
         --  is done in Try_Object_Operation) to prevent back-end confusion;
         --  for the function entity itself. The call must appear in a context
         --  where the nonlimited view is available. If the function entity is
         --  in the extended main unit then no action is needed, because the
         --  back end handles this case. In either case the type of the call
         --  is the nonlimited view.

         if From_Limited_With (Etype (Nam))
           and then Present (Available_View (Etype (Nam)))
         then
            Set_Etype (N, Available_View (Etype (Nam)));

            if not In_Extended_Main_Code_Unit (Nam) then
               Set_Etype (Nam, Available_View (Etype (Nam)));
            end if;

         else
            Set_Etype (N, Etype (Nam));
         end if;
      end if;

      --  In the case where the call is to an overloaded subprogram, Analyze
      --  calls Normalize_Actuals once per overloaded subprogram. Therefore in
      --  such a case Normalize_Actuals needs to be called once more to order
      --  the actuals correctly. Otherwise the call will have the ordering
      --  given by the last overloaded subprogram whether this is the correct
      --  one being called or not.

      if Is_Overloaded (Subp) then
         Normalize_Actuals (N, Nam, False, Norm_OK);
         pragma Assert (Norm_OK);
      end if;

      --  In any case, call is fully resolved now. Reset Overload flag, to
      --  prevent subsequent overload resolution if node is analyzed again

      Set_Is_Overloaded (Subp, False);
      Set_Is_Overloaded (N, False);

      --  A Ghost entity must appear in a specific context

      if Is_Ghost_Entity (Nam) and then Comes_From_Source (N) then
         Check_Ghost_Context (Nam, N);
      end if;

      --  If we are calling the current subprogram from immediately within its
      --  body, then that is the case where we can sometimes detect cases of
      --  infinite recursion statically. Do not try this in case restriction
      --  No_Recursion is in effect anyway, and do it only for source calls.

      if Comes_From_Source (N) then
         Scop := Current_Scope;

         --  Check violation of SPARK_05 restriction which does not permit
         --  a subprogram body to contain a call to the subprogram directly.

         if Restriction_Check_Required (SPARK_05)
           and then Same_Or_Aliased_Subprograms (Nam, Scop)
         then
            Check_SPARK_05_Restriction
              ("subprogram may not contain direct call to itself", N);
         end if;

         --  Issue warning for possible infinite recursion in the absence
         --  of the No_Recursion restriction.

         if Same_Or_Aliased_Subprograms (Nam, Scop)
           and then not Restriction_Active (No_Recursion)
           and then Check_Infinite_Recursion (N)
         then
            --  Here we detected and flagged an infinite recursion, so we do
            --  not need to test the case below for further warnings. Also we
            --  are all done if we now have a raise SE node.

            if Nkind (N) = N_Raise_Storage_Error then
               return;
            end if;

         --  If call is to immediately containing subprogram, then check for
         --  the case of a possible run-time detectable infinite recursion.

         else
            Scope_Loop : while Scop /= Standard_Standard loop
               if Same_Or_Aliased_Subprograms (Nam, Scop) then

                  --  Although in general case, recursion is not statically
                  --  checkable, the case of calling an immediately containing
                  --  subprogram is easy to catch.

                  if not Is_Ignored_Ghost_Entity (Nam) then
                     Check_Restriction (No_Recursion, N);
                  end if;

                  --  If the recursive call is to a parameterless subprogram,
                  --  then even if we can't statically detect infinite
                  --  recursion, this is pretty suspicious, and we output a
                  --  warning. Furthermore, we will try later to detect some
                  --  cases here at run time by expanding checking code (see
                  --  Detect_Infinite_Recursion in package Exp_Ch6).

                  --  If the recursive call is within a handler, do not emit a
                  --  warning, because this is a common idiom: loop until input
                  --  is correct, catch illegal input in handler and restart.

                  if No (First_Formal (Nam))
                    and then Etype (Nam) = Standard_Void_Type
                    and then not Error_Posted (N)
                    and then Nkind (Parent (N)) /= N_Exception_Handler
                  then
                     --  For the case of a procedure call. We give the message
                     --  only if the call is the first statement in a sequence
                     --  of statements, or if all previous statements are
                     --  simple assignments. This is simply a heuristic to
                     --  decrease false positives, without losing too many good
                     --  warnings. The idea is that these previous statements
                     --  may affect global variables the procedure depends on.
                     --  We also exclude raise statements, that may arise from
                     --  constraint checks and are probably unrelated to the
                     --  intended control flow.

                     if Nkind (N) = N_Procedure_Call_Statement
                       and then Is_List_Member (N)
                     then
                        declare
                           P : Node_Id;
                        begin
                           P := Prev (N);
                           while Present (P) loop
                              if not Nkind_In (P, N_Assignment_Statement,
                                                  N_Raise_Constraint_Error)
                              then
                                 exit Scope_Loop;
                              end if;

                              Prev (P);
                           end loop;
                        end;
                     end if;

                     --  Do not give warning if we are in a conditional context

                     declare
                        K : constant Node_Kind := Nkind (Parent (N));
                     begin
                        if (K = N_Loop_Statement
                             and then Present (Iteration_Scheme (Parent (N))))
                          or else K = N_If_Statement
                          or else K = N_Elsif_Part
                          or else K = N_Case_Statement_Alternative
                        then
                           exit Scope_Loop;
                        end if;
                     end;

                     --  Here warning is to be issued

                     Set_Has_Recursive_Call (Nam);
                     Error_Msg_Warn := SPARK_Mode /= On;
                     Error_Msg_N ("possible infinite recursion<<!", N);
                     Error_Msg_N ("\Storage_Error ]<<!", N);
                  end if;

                  exit Scope_Loop;
               end if;

               Scop := Scope (Scop);
            end loop Scope_Loop;
         end if;
      end if;

      --  Check obsolescent reference to Ada.Characters.Handling subprogram

      Check_Obsolescent_2005_Entity (Nam, Subp);

      --  If subprogram name is a predefined operator, it was given in
      --  functional notation. Replace call node with operator node, so
      --  that actuals can be resolved appropriately.

      if Is_Predefined_Op (Nam) or else Ekind (Nam) = E_Operator then
         Make_Call_Into_Operator (N, Typ, Entity (Name (N)));
         return;

      elsif Present (Alias (Nam))
        and then Is_Predefined_Op (Alias (Nam))
      then
         Resolve_Actuals (N, Nam);
         Make_Call_Into_Operator (N, Typ, Alias (Nam));
         return;
      end if;

      --  Create a transient scope if the resulting type requires it

      --  There are several notable exceptions:

      --  a) In init procs, the transient scope overhead is not needed, and is
      --  even incorrect when the call is a nested initialization call for a
      --  component whose expansion may generate adjust calls. However, if the
      --  call is some other procedure call within an initialization procedure
      --  (for example a call to Create_Task in the init_proc of the task
      --  run-time record) a transient scope must be created around this call.

      --  b) Enumeration literal pseudo-calls need no transient scope

      --  c) Intrinsic subprograms (Unchecked_Conversion and source info
      --  functions) do not use the secondary stack even though the return
      --  type may be unconstrained.

      --  d) Calls to a build-in-place function, since such functions may
      --  allocate their result directly in a target object, and cases where
      --  the result does get allocated in the secondary stack are checked for
      --  within the specialized Exp_Ch6 procedures for expanding those
      --  build-in-place calls.

      --  e) Calls to inlinable expression functions do not use the secondary
      --  stack (since the call will be replaced by its returned object).

      --  f) If the subprogram is marked Inline_Always, then even if it returns
      --  an unconstrained type the call does not require use of the secondary
      --  stack. However, inlining will only take place if the body to inline
      --  is already present. It may not be available if e.g. the subprogram is
      --  declared in a child instance.

      if Is_Inlined (Nam)
        and then Has_Pragma_Inline (Nam)
        and then Nkind (Unit_Declaration_Node (Nam)) = N_Subprogram_Declaration
        and then Present (Body_To_Inline (Unit_Declaration_Node (Nam)))
      then
         null;

      elsif Ekind (Nam) = E_Enumeration_Literal
        or else Is_Build_In_Place_Function (Nam)
        or else Is_Intrinsic_Subprogram (Nam)
        or else Is_Inlinable_Expression_Function (Nam)
      then
         null;

      --  A return statement from an ignored Ghost function does not use the
      --  secondary stack (or any other one).

      elsif Expander_Active
        and then Ekind_In (Nam, E_Function, E_Subprogram_Type)
        and then Requires_Transient_Scope (Etype (Nam))
        and then not Is_Ignored_Ghost_Entity (Nam)
      then
         Establish_Transient_Scope (N, Manage_Sec_Stack => True);

         --  If the call appears within the bounds of a loop, it will be
         --  rewritten and reanalyzed, nothing left to do here.

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

      --  A protected function cannot be called within the definition of the
      --  enclosing protected type, unless it is part of a pre/postcondition
      --  on another protected operation. This may appear in the entry wrapper
      --  created for an entry with preconditions.

      if Is_Protected_Type (Scope (Nam))
        and then In_Open_Scopes (Scope (Nam))
        and then not Has_Completion (Scope (Nam))
        and then not In_Spec_Expression
        and then not Is_Entry_Wrapper (Current_Scope)
      then
         Error_Msg_NE
           ("& cannot be called before end of protected definition", N, Nam);
      end if;

      --  Propagate interpretation to actuals, and add default expressions
      --  where needed.

      if Present (First_Formal (Nam)) then
         Resolve_Actuals (N, Nam);

      --  Overloaded literals are rewritten as function calls, for purpose of
      --  resolution. After resolution, we can replace the call with the
      --  literal itself.

      elsif Ekind (Nam) = E_Enumeration_Literal then
         Copy_Node (Subp, N);
         Resolve_Entity_Name (N, Typ);

         --  Avoid validation, since it is a static function call

         Generate_Reference (Nam, Subp);
         return;
      end if;

      --  If the subprogram is not global, then kill all saved values and
      --  checks. This is a bit conservative, since in many cases we could do
      --  better, but it is not worth the effort. Similarly, we kill constant
      --  values. However we do not need to do this for internal entities
      --  (unless they are inherited user-defined subprograms), since they
      --  are not in the business of molesting local values.

      --  If the flag Suppress_Value_Tracking_On_Calls is set, then we also
      --  kill all checks and values for calls to global subprograms. This
      --  takes care of the case where an access to a local subprogram is
      --  taken, and could be passed directly or indirectly and then called
      --  from almost any context.

      --  Note: we do not do this step till after resolving the actuals. That
      --  way we still take advantage of the current value information while
      --  scanning the actuals.

      --  We suppress killing values if we are processing the nodes associated
      --  with N_Freeze_Entity nodes. Otherwise the declaration of a tagged
      --  type kills all the values as part of analyzing the code that
      --  initializes the dispatch tables.

      if Inside_Freezing_Actions = 0
        and then (not Is_Library_Level_Entity (Nam)
                   or else Suppress_Value_Tracking_On_Call
                             (Nearest_Dynamic_Scope (Current_Scope)))
        and then (Comes_From_Source (Nam)
                   or else (Present (Alias (Nam))
                             and then Comes_From_Source (Alias (Nam))))
      then
         Kill_Current_Values;
      end if;

      --  If we are warning about unread OUT parameters, this is the place to
      --  set Last_Assignment for OUT and IN OUT parameters. We have to do this
      --  after the above call to Kill_Current_Values (since that call clears
      --  the Last_Assignment field of all local variables).

      if (Warn_On_Modified_Unread or Warn_On_All_Unread_Out_Parameters)
        and then Comes_From_Source (N)
        and then In_Extended_Main_Source_Unit (N)
      then
         declare
            F : Entity_Id;
            A : Node_Id;

         begin
            F := First_Formal (Nam);
            A := First_Actual (N);
            while Present (F) and then Present (A) loop
               if Ekind_In (F, E_Out_Parameter, E_In_Out_Parameter)
                 and then Warn_On_Modified_As_Out_Parameter (F)
                 and then Is_Entity_Name (A)
                 and then Present (Entity (A))
                 and then Comes_From_Source (N)
                 and then Safe_To_Capture_Value (N, Entity (A))
               then
                  Set_Last_Assignment (Entity (A), A);
               end if;

               Next_Formal (F);
               Next_Actual (A);
            end loop;
         end;
      end if;

      --  If the subprogram is a primitive operation, check whether or not
      --  it is a correct dispatching call.

      if Is_Overloadable (Nam)
        and then Is_Dispatching_Operation (Nam)
      then
         Check_Dispatching_Call (N);

      elsif Ekind (Nam) /= E_Subprogram_Type
        and then Is_Abstract_Subprogram (Nam)
        and then not In_Instance
      then
         Error_Msg_NE ("cannot call abstract subprogram &!", N, Nam);
      end if;

      --  If this is a dispatching call, generate the appropriate reference,
      --  for better source navigation in GNAT Studio.

      if Is_Overloadable (Nam)
        and then Present (Controlling_Argument (N))
      then
         Generate_Reference (Nam, Subp, 'R');

      --  Normal case, not a dispatching call: generate a call reference

      else
         Generate_Reference (Nam, Subp, 's');
      end if;

      if Is_Intrinsic_Subprogram (Nam) then
         Check_Intrinsic_Call (N);
      end if;

      --  Check for violation of restriction No_Specific_Termination_Handlers
      --  and warn on a potentially blocking call to Abort_Task.

      if Restriction_Check_Required (No_Specific_Termination_Handlers)
        and then (Is_RTE (Nam, RE_Set_Specific_Handler)
                    or else
                  Is_RTE (Nam, RE_Specific_Handler))
      then
         Check_Restriction (No_Specific_Termination_Handlers, N);

      elsif Is_RTE (Nam, RE_Abort_Task) then
         Check_Potentially_Blocking_Operation (N);
      end if;

      --  A call to Ada.Real_Time.Timing_Events.Set_Handler to set a relative
      --  timing event violates restriction No_Relative_Delay (AI-0211). We
      --  need to check the second argument to determine whether it is an
      --  absolute or relative timing event.

      if Restriction_Check_Required (No_Relative_Delay)
        and then Is_RTE (Nam, RE_Set_Handler)
        and then Is_RTE (Etype (Next_Actual (First_Actual (N))), RE_Time_Span)
      then
         Check_Restriction (No_Relative_Delay, N);
      end if;

      --  Issue an error for a call to an eliminated subprogram. This routine
      --  will not perform the check if the call appears within a default
      --  expression.

      Check_For_Eliminated_Subprogram (Subp, Nam);

      --  In formal mode, the primitive operations of a tagged type or type
      --  extension do not include functions that return the tagged type.

      if Nkind (N) = N_Function_Call
        and then Is_Tagged_Type (Etype (N))
        and then Is_Entity_Name (Name (N))
        and then Is_Inherited_Operation_For_Type (Entity (Name (N)), Etype (N))
      then
         Check_SPARK_05_Restriction ("function not inherited", N);
      end if;

      --  Implement rule in 12.5.1 (23.3/2): In an instance, if the actual is
      --  class-wide and the call dispatches on result in a context that does
      --  not provide a tag, the call raises Program_Error.

      if Nkind (N) = N_Function_Call
        and then In_Instance
        and then Is_Generic_Actual_Type (Typ)
        and then Is_Class_Wide_Type (Typ)
        and then Has_Controlling_Result (Nam)
        and then Nkind (Parent (N)) = N_Object_Declaration
      then
         --  Verify that none of the formals are controlling

         declare
            Call_OK : Boolean := False;
            F       : Entity_Id;

         begin
            F := First_Formal (Nam);
            while Present (F) loop
               if Is_Controlling_Formal (F) then
                  Call_OK := True;
                  exit;
               end if;

               Next_Formal (F);
            end loop;

            if not Call_OK then
               Error_Msg_Warn := SPARK_Mode /= On;
               Error_Msg_N ("!cannot determine tag of result<<", N);
               Error_Msg_N ("\Program_Error [<<!", N);
               Insert_Action (N,
                 Make_Raise_Program_Error (Sloc (N),
                    Reason => PE_Explicit_Raise));
            end if;
         end;
      end if;

      --  Check for calling a function with OUT or IN OUT parameter when the
      --  calling context (us right now) is not Ada 2012, so does not allow
      --  OUT or IN OUT parameters in function calls. Functions declared in
      --  a predefined unit are OK, as they may be called indirectly from a
      --  user-declared instantiation.

      if Ada_Version < Ada_2012
        and then Ekind (Nam) = E_Function
        and then Has_Out_Or_In_Out_Parameter (Nam)
        and then not In_Predefined_Unit (Nam)
      then
         Error_Msg_NE ("& has at least one OUT or `IN OUT` parameter", N, Nam);
         Error_Msg_N ("\call to this function only allowed in Ada 2012", N);
      end if;

      --  Check the dimensions of the actuals in the call. For function calls,
      --  propagate the dimensions from the returned type to N.

      Analyze_Dimension_Call (N, Nam);

      --  All done, evaluate call and deal with elaboration issues

      Eval_Call (N);

      if Legacy_Elaboration_Checks then
         Check_Elab_Call (N);
      end if;

      --  Annotate the tree by creating a call marker in case the original call
      --  is transformed by expansion. The call marker is automatically saved
      --  for later examination by the ABE Processing phase.

      Build_Call_Marker (N);

      Mark_Use_Clauses (Subp);

      Warn_On_Overlapping_Actuals (Nam, N);

      --  In GNATprove mode, expansion is disabled, but we want to inline some
      --  subprograms to facilitate formal verification. Indirect calls through
      --  a subprogram type or within a generic cannot be inlined. Inlining is
      --  performed only for calls subject to SPARK_Mode on.

      if GNATprove_Mode
        and then SPARK_Mode = On
        and then Is_Overloadable (Nam)
        and then not Inside_A_Generic
      then
         Nam_UA   := Ultimate_Alias (Nam);
         Nam_Decl := Unit_Declaration_Node (Nam_UA);

         if Nkind (Nam_Decl) = N_Subprogram_Declaration then
            Body_Id := Corresponding_Body (Nam_Decl);

            --  Nothing to do if the subprogram is not eligible for inlining in
            --  GNATprove mode, or inlining is disabled with switch -gnatdm

            if not Is_Inlined_Always (Nam_UA)
              or else not Can_Be_Inlined_In_GNATprove_Mode (Nam_UA, Body_Id)
              or else Debug_Flag_M
            then
               null;

            --  Calls cannot be inlined inside assertions, as GNATprove treats
            --  assertions as logic expressions. Only issue a message when the
            --  body has been seen, otherwise this leads to spurious messages
            --  on expression functions.

            elsif In_Assertion_Expr /= 0 then
               if Present (Body_Id) then
                  Cannot_Inline
                    ("cannot inline & (in assertion expression)?", N, Nam_UA);
               end if;

            --  Calls cannot be inlined inside default expressions

            elsif In_Default_Expr then
               Cannot_Inline
                 ("cannot inline & (in default expression)?", N, Nam_UA);

            --  Calls cannot be inlined inside quantified expressions, which
            --  are left in expression form for GNATprove. Since these
            --  expressions are only preanalyzed, we need to detect the failure
            --  to inline outside of the case for Full_Analysis below.

            elsif In_Quantified_Expression (N) then
               Cannot_Inline
                 ("cannot inline & (in quantified expression)?", N, Nam_UA);

            --  Inlining should not be performed during preanalysis

            elsif Full_Analysis then

               --  Do not inline calls inside expression functions or functions
               --  generated by the front end for subtype predicates, as this
               --  would prevent interpreting them as logical formulas in
               --  GNATprove. Only issue a message when the body has been seen,
               --  otherwise this leads to spurious messages on callees that
               --  are themselves expression functions.

               if Present (Current_Subprogram)
                 and then
                   (Is_Expression_Function_Or_Completion (Current_Subprogram)
                     or else Is_Predicate_Function (Current_Subprogram)
                     or else Is_Invariant_Procedure (Current_Subprogram)
                     or else Is_DIC_Procedure (Current_Subprogram))
               then
                  if Present (Body_Id)
                    and then Present (Body_To_Inline (Nam_Decl))
                  then
                     if Is_Predicate_Function (Current_Subprogram) then
                        Cannot_Inline
                          ("cannot inline & (inside predicate)?",
                           N, Nam_UA);

                     elsif Is_Invariant_Procedure (Current_Subprogram) then
                        Cannot_Inline
                          ("cannot inline & (inside invariant)?",
                           N, Nam_UA);

                     elsif Is_DIC_Procedure (Current_Subprogram) then
                        Cannot_Inline
                        ("cannot inline & (inside Default_Initial_Condition)?",
                         N, Nam_UA);

                     else
                        Cannot_Inline
                          ("cannot inline & (inside expression function)?",
                           N, Nam_UA);
                     end if;
                  end if;

               --  Cannot inline a call inside the definition of a record type,
               --  typically inside the constraints of the type. Calls in
               --  default expressions are also not inlined, but this is
               --  filtered out above when testing In_Default_Expr.

               elsif Is_Record_Type (Current_Scope) then
                  Cannot_Inline
                    ("cannot inline & (inside record type)?", N, Nam_UA);

               --  With the one-pass inlining technique, a call cannot be
               --  inlined if the corresponding body has not been seen yet.

               elsif No (Body_Id) then
                  Cannot_Inline
                    ("cannot inline & (body not seen yet)?", N, Nam_UA);

               --  Nothing to do if there is no body to inline, indicating that
               --  the subprogram is not suitable for inlining in GNATprove
               --  mode.

               elsif No (Body_To_Inline (Nam_Decl)) then
                  null;

               --  Calls cannot be inlined inside potentially unevaluated
               --  expressions, as this would create complex actions inside
               --  expressions, that are not handled by GNATprove.

               elsif Is_Potentially_Unevaluated (N) then
                  Cannot_Inline
                    ("cannot inline & (in potentially unevaluated context)?",
                     N, Nam_UA);

               --  Calls cannot be inlined inside the conditions of while
               --  loops, as this would create complex actions inside
               --  the condition, that are not handled by GNATprove.

               elsif In_While_Loop_Condition (N) then
                  Cannot_Inline
                    ("cannot inline & (in while loop condition)?", N, Nam_UA);

               --  Do not inline calls which would possibly lead to missing a
               --  type conversion check on an input parameter.

               elsif not Call_Can_Be_Inlined_In_GNATprove_Mode (N, Nam) then
                  Cannot_Inline
                    ("cannot inline & (possible check on input parameters)?",
                     N, Nam_UA);

               --  Otherwise, inline the call, issuing an info message when
               --  -gnatd_f is set.

               else
                  if Debug_Flag_Underscore_F then
                     Error_Msg_NE
                       ("info: analyzing call to & in context?", N, Nam_UA);
                  end if;

                  Expand_Inlined_Call (N, Nam_UA, Nam);
               end if;
            end if;
         end if;
      end if;
   end Resolve_Call;

   -----------------------------
   -- Resolve_Case_Expression --
   -----------------------------

   procedure Resolve_Case_Expression (N : Node_Id; Typ : Entity_Id) is
      Alt      : Node_Id;
      Alt_Expr : Node_Id;
      Alt_Typ  : Entity_Id;
      Is_Dyn   : Boolean;

   begin
      Alt := First (Alternatives (N));
      while Present (Alt) loop
         Alt_Expr := Expression (Alt);

         if Error_Posted (Alt_Expr) then
            return;
         end if;

         Resolve (Alt_Expr, Typ);
         Alt_Typ := Etype (Alt_Expr);

         --  When the expression is of a scalar subtype different from the
         --  result subtype, then insert a conversion to ensure the generation
         --  of a constraint check.

         if Is_Scalar_Type (Alt_Typ) and then Alt_Typ /= Typ then
            Rewrite (Alt_Expr, Convert_To (Typ, Alt_Expr));
            Analyze_And_Resolve (Alt_Expr, Typ);
         end if;

         Next (Alt);
      end loop;

      --  Apply RM 4.5.7 (17/3): whether the expression is statically or
      --  dynamically tagged must be known statically.

      if Is_Tagged_Type (Typ) and then not Is_Class_Wide_Type (Typ) then
         Alt    := First (Alternatives (N));
         Is_Dyn := Is_Dynamically_Tagged (Expression (Alt));

         while Present (Alt) loop
            if Is_Dynamically_Tagged (Expression (Alt)) /= Is_Dyn then
               Error_Msg_N
                 ("all or none of the dependent expressions can be "
                  & "dynamically tagged", N);
            end if;

            Next (Alt);
         end loop;
      end if;

      Set_Etype (N, Typ);
      Eval_Case_Expression (N);
      Analyze_Dimension (N);
   end Resolve_Case_Expression;

   -------------------------------
   -- Resolve_Character_Literal --
   -------------------------------

   procedure Resolve_Character_Literal (N : Node_Id; Typ : Entity_Id) is
      B_Typ : constant Entity_Id := Base_Type (Typ);
      C     : Entity_Id;

   begin
      --  Verify that the character does belong to the type of the context

      Set_Etype (N, B_Typ);
      Eval_Character_Literal (N);

      --  Wide_Wide_Character literals must always be defined, since the set
      --  of wide wide character literals is complete, i.e. if a character
      --  literal is accepted by the parser, then it is OK for wide wide
      --  character (out of range character literals are rejected).

      if Root_Type (B_Typ) = Standard_Wide_Wide_Character then
         return;

      --  Always accept character literal for type Any_Character, which
      --  occurs in error situations and in comparisons of literals, both
      --  of which should accept all literals.

      elsif B_Typ = Any_Character then
         return;

      --  For Standard.Character or a type derived from it, check that the
      --  literal is in range.

      elsif Root_Type (B_Typ) = Standard_Character then
         if In_Character_Range (UI_To_CC (Char_Literal_Value (N))) then
            return;
         end if;

      --  For Standard.Wide_Character or a type derived from it, check that the
      --  literal is in range.

      elsif Root_Type (B_Typ) = Standard_Wide_Character then
         if In_Wide_Character_Range (UI_To_CC (Char_Literal_Value (N))) then
            return;
         end if;

      --  If the entity is already set, this has already been resolved in a
      --  generic context, or comes from expansion. Nothing else to do.

      elsif Present (Entity (N)) then
         return;

      --  Otherwise we have a user defined character type, and we can use the
      --  standard visibility mechanisms to locate the referenced entity.

      else
         C := Current_Entity (N);
         while Present (C) loop
            if Etype (C) = B_Typ then
               Set_Entity_With_Checks (N, C);
               Generate_Reference (C, N);
               return;
            end if;

            C := Homonym (C);
         end loop;
      end if;

      --  If we fall through, then the literal does not match any of the
      --  entries of the enumeration type. This isn't just a constraint error
      --  situation, it is an illegality (see RM 4.2).

      Error_Msg_NE
        ("character not defined for }", N, First_Subtype (B_Typ));
   end Resolve_Character_Literal;

   ---------------------------
   -- Resolve_Comparison_Op --
   ---------------------------

   --  Context requires a boolean type, and plays no role in resolution.
   --  Processing identical to that for equality operators. The result type is
   --  the base type, which matters when pathological subtypes of booleans with
   --  limited ranges are used.

   procedure Resolve_Comparison_Op (N : Node_Id; Typ : Entity_Id) is
      L : constant Node_Id := Left_Opnd (N);
      R : constant Node_Id := Right_Opnd (N);
      T : Entity_Id;

   begin
      --  If this is an intrinsic operation which is not predefined, use the
      --  types of its declared arguments to resolve the possibly overloaded
      --  operands. Otherwise the operands are unambiguous and specify the
      --  expected type.

      if Scope (Entity (N)) /= Standard_Standard then
         T := Etype (First_Entity (Entity (N)));

      else
         T := Find_Unique_Type (L, R);

         if T = Any_Fixed then
            T := Unique_Fixed_Point_Type (L);
         end if;
      end if;

      Set_Etype (N, Base_Type (Typ));
      Generate_Reference (T, N, ' ');

      --  Skip remaining processing if already set to Any_Type

      if T = Any_Type then
         return;
      end if;

      --  Deal with other error cases

      if T = Any_String    or else
         T = Any_Composite or else
         T = Any_Character
      then
         if T = Any_Character then
            Ambiguous_Character (L);
         else
            Error_Msg_N ("ambiguous operands for comparison", N);
         end if;

         Set_Etype (N, Any_Type);
         return;
      end if;

      --  Resolve the operands if types OK

      Resolve (L, T);
      Resolve (R, T);
      Check_Unset_Reference (L);
      Check_Unset_Reference (R);
      Generate_Operator_Reference (N, T);
      Check_Low_Bound_Tested (N);

      --  In SPARK, ordering operators <, <=, >, >= are not defined for Boolean
      --  types or array types except String.

      if Is_Boolean_Type (T) then
         Check_SPARK_05_Restriction
           ("comparison is not defined on Boolean type", N);

      elsif Is_Array_Type (T)
        and then Base_Type (T) /= Standard_String
      then
         Check_SPARK_05_Restriction
           ("comparison is not defined on array types other than String", N);
      end if;

      --  Check comparison on unordered enumeration

      if Bad_Unordered_Enumeration_Reference (N, Etype (L)) then
         Error_Msg_Sloc := Sloc (Etype (L));
         Error_Msg_NE
           ("comparison on unordered enumeration type& declared#?U?",
            N, Etype (L));
      end if;

      Analyze_Dimension (N);

      --  Evaluate the relation (note we do this after the above check since
      --  this Eval call may change N to True/False. Skip this evaluation
      --  inside assertions, in order to keep assertions as written by users
      --  for tools that rely on these, e.g. GNATprove for loop invariants.
      --  Except evaluation is still performed even inside assertions for
      --  comparisons between values of universal type, which are useless
      --  for static analysis tools, and not supported even by GNATprove.

      if In_Assertion_Expr = 0
        or else (Is_Universal_Numeric_Type (Etype (L))
                   and then
                 Is_Universal_Numeric_Type (Etype (R)))
      then
         Eval_Relational_Op (N);
      end if;
   end Resolve_Comparison_Op;

   -----------------------------------------
   -- Resolve_Discrete_Subtype_Indication --
   -----------------------------------------

   procedure Resolve_Discrete_Subtype_Indication
     (N   : Node_Id;
      Typ : Entity_Id)
   is
      R : Node_Id;
      S : Entity_Id;

   begin
      Analyze (Subtype_Mark (N));
      S := Entity (Subtype_Mark (N));

      if Nkind (Constraint (N)) /= N_Range_Constraint then
         Error_Msg_N ("expect range constraint for discrete type", N);
         Set_Etype (N, Any_Type);

      else
         R := Range_Expression (Constraint (N));

         if R = Error then
            return;
         end if;

         Analyze (R);

         if Base_Type (S) /= Base_Type (Typ) then
            Error_Msg_NE
              ("expect subtype of }", N, First_Subtype (Typ));

            --  Rewrite the constraint as a range of Typ
            --  to allow compilation to proceed further.

            Set_Etype (N, Typ);
            Rewrite (Low_Bound (R),
              Make_Attribute_Reference (Sloc (Low_Bound (R)),
                Prefix         => New_Occurrence_Of (Typ, Sloc (R)),
                Attribute_Name => Name_First));
            Rewrite (High_Bound (R),
              Make_Attribute_Reference (Sloc (High_Bound (R)),
                Prefix         => New_Occurrence_Of (Typ, Sloc (R)),
                Attribute_Name => Name_First));

         else
            Resolve (R, Typ);
            Set_Etype (N, Etype (R));

            --  Additionally, we must check that the bounds are compatible
            --  with the given subtype, which might be different from the
            --  type of the context.

            Apply_Range_Check (R, S);

            --  ??? If the above check statically detects a Constraint_Error
            --  it replaces the offending bound(s) of the range R with a
            --  Constraint_Error node. When the itype which uses these bounds
            --  is frozen the resulting call to Duplicate_Subexpr generates
            --  a new temporary for the bounds.

            --  Unfortunately there are other itypes that are also made depend
            --  on these bounds, so when Duplicate_Subexpr is called they get
            --  a forward reference to the newly created temporaries and Gigi
            --  aborts on such forward references. This is probably sign of a
            --  more fundamental problem somewhere else in either the order of
            --  itype freezing or the way certain itypes are constructed.

            --  To get around this problem we call Remove_Side_Effects right
            --  away if either bounds of R are a Constraint_Error.

            declare
               L : constant Node_Id := Low_Bound (R);
               H : constant Node_Id := High_Bound (R);

            begin
               if Nkind (L) = N_Raise_Constraint_Error then
                  Remove_Side_Effects (L);
               end if;

               if Nkind (H) = N_Raise_Constraint_Error then
                  Remove_Side_Effects (H);
               end if;
            end;

            Check_Unset_Reference (Low_Bound  (R));
            Check_Unset_Reference (High_Bound (R));
         end if;
      end if;
   end Resolve_Discrete_Subtype_Indication;

   -------------------------
   -- Resolve_Entity_Name --
   -------------------------

   --  Used to resolve identifiers and expanded names

   procedure Resolve_Entity_Name (N : Node_Id; Typ : Entity_Id) is
      function Is_Assignment_Or_Object_Expression
        (Context : Node_Id;
         Expr    : Node_Id) return Boolean;
      --  Determine whether node Context denotes an assignment statement or an
      --  object declaration whose expression is node Expr.

      ----------------------------------------
      -- Is_Assignment_Or_Object_Expression --
      ----------------------------------------

      function Is_Assignment_Or_Object_Expression
        (Context : Node_Id;
         Expr    : Node_Id) return Boolean
      is
      begin
         if Nkind_In (Context, N_Assignment_Statement,
                               N_Object_Declaration)
           and then Expression (Context) = Expr
         then
            return True;

         --  Check whether a construct that yields a name is the expression of
         --  an assignment statement or an object declaration.

         elsif (Nkind_In (Context, N_Attribute_Reference,
                                   N_Explicit_Dereference,
                                   N_Indexed_Component,
                                   N_Selected_Component,
                                   N_Slice)
                  and then Prefix (Context) = Expr)
           or else
               (Nkind_In (Context, N_Type_Conversion,
                                   N_Unchecked_Type_Conversion)
                  and then Expression (Context) = Expr)
         then
            return
              Is_Assignment_Or_Object_Expression
                (Context => Parent (Context),
                 Expr    => Context);

         --  Otherwise the context is not an assignment statement or an object
         --  declaration.

         else
            return False;
         end if;
      end Is_Assignment_Or_Object_Expression;

      --  Local variables

      E   : constant Entity_Id := Entity (N);
      Par : Node_Id;

   --  Start of processing for Resolve_Entity_Name

   begin
      --  If garbage from errors, set to Any_Type and return

      if No (E) and then Total_Errors_Detected /= 0 then
         Set_Etype (N, Any_Type);
         return;
      end if;

      --  Replace named numbers by corresponding literals. Note that this is
      --  the one case where Resolve_Entity_Name must reset the Etype, since
      --  it is currently marked as universal.

      if Ekind (E) = E_Named_Integer then
         Set_Etype (N, Typ);
         Eval_Named_Integer (N);

      elsif Ekind (E) = E_Named_Real then
         Set_Etype (N, Typ);
         Eval_Named_Real (N);

      --  For enumeration literals, we need to make sure that a proper style
      --  check is done, since such literals are overloaded, and thus we did
      --  not do a style check during the first phase of analysis.

      elsif Ekind (E) = E_Enumeration_Literal then
         Set_Entity_With_Checks (N, E);
         Eval_Entity_Name (N);

      --  Case of (sub)type name appearing in a context where an expression
      --  is expected. This is legal if occurrence is a current instance.
      --  See RM 8.6 (17/3).

      elsif Is_Type (E) then
         if Is_Current_Instance (N) then
            null;

         --  Any other use is an error

         else
            Error_Msg_N
              ("invalid use of subtype mark in expression or call", N);
         end if;

      --  Check discriminant use if entity is discriminant in current scope,
      --  i.e. discriminant of record or concurrent type currently being
      --  analyzed. Uses in corresponding body are unrestricted.

      elsif Ekind (E) = E_Discriminant
        and then Scope (E) = Current_Scope
        and then not Has_Completion (Current_Scope)
      then
         Check_Discriminant_Use (N);

      --  A parameterless generic function cannot appear in a context that
      --  requires resolution.

      elsif Ekind (E) = E_Generic_Function then
         Error_Msg_N ("illegal use of generic function", N);

      --  In Ada 83 an OUT parameter cannot be read, but attributes of
      --  array types (i.e. bounds and length) are legal.

      elsif Ekind (E) = E_Out_Parameter
        and then (Nkind (Parent (N)) /= N_Attribute_Reference
                   or else Is_Scalar_Type (Etype (E)))

        and then (Nkind (Parent (N)) in N_Op
                   or else Nkind (Parent (N)) = N_Explicit_Dereference
                   or else Is_Assignment_Or_Object_Expression
                             (Context => Parent (N),
                              Expr    => N))
      then
         if Ada_Version = Ada_83 then
            Error_Msg_N ("(Ada 83) illegal reading of out parameter", N);
         end if;

      --  In all other cases, just do the possible static evaluation

      else
         --  A deferred constant that appears in an expression must have a
         --  completion, unless it has been removed by in-place expansion of
         --  an aggregate. A constant that is a renaming does not need
         --  initialization.

         if Ekind (E) = E_Constant
           and then Comes_From_Source (E)
           and then No (Constant_Value (E))
           and then Is_Frozen (Etype (E))
           and then not In_Spec_Expression
           and then not Is_Imported (E)
           and then Nkind (Parent (E)) /= N_Object_Renaming_Declaration
         then
            if No_Initialization (Parent (E))
              or else (Present (Full_View (E))
                        and then No_Initialization (Parent (Full_View (E))))
            then
               null;
            else
               Error_Msg_N
                 ("deferred constant is frozen before completion", N);
            end if;
         end if;

         Eval_Entity_Name (N);
      end if;

      Par := Parent (N);

      --  When the entity appears in a parameter association, retrieve the
      --  related subprogram call.

      if Nkind (Par) = N_Parameter_Association then
         Par := Parent (Par);
      end if;

      if Comes_From_Source (N) then

         --  The following checks are only relevant when SPARK_Mode is on as
         --  they are not standard Ada legality rules.

         if SPARK_Mode = On then

            --  An effectively volatile object subject to enabled properties
            --  Async_Writers or Effective_Reads must appear in non-interfering
            --  context (SPARK RM 7.1.3(12)).

            if Is_Object (E)
              and then Is_Effectively_Volatile (E)
              and then (Async_Writers_Enabled (E)
                         or else Effective_Reads_Enabled (E))
              and then not Is_OK_Volatile_Context (Par, N)
            then
               SPARK_Msg_N
                 ("volatile object cannot appear in this context "
                  & "(SPARK RM 7.1.3(12))", N);
            end if;

            --  Check for possible elaboration issues with respect to reads of
            --  variables. The act of renaming the variable is not considered a
            --  read as it simply establishes an alias.

            if Legacy_Elaboration_Checks
              and then Ekind (E) = E_Variable
              and then Dynamic_Elaboration_Checks
              and then Nkind (Par) /= N_Object_Renaming_Declaration
            then
               Check_Elab_Call (N);
            end if;
         end if;

         --  The variable may eventually become a constituent of a single
         --  protected/task type. Record the reference now and verify its
         --  legality when analyzing the contract of the variable
         --  (SPARK RM 9.3).

         if Ekind (E) = E_Variable then
            Record_Possible_Part_Of_Reference (E, N);
         end if;

         --  A Ghost entity must appear in a specific context

         if Is_Ghost_Entity (E) then
            Check_Ghost_Context (E, N);
         end if;
      end if;

      --  We may be resolving an entity within expanded code, so a reference to
      --  an entity should be ignored when calculating effective use clauses to
      --  avoid inappropriate marking.

      if Comes_From_Source (N) then
         Mark_Use_Clauses (E);
      end if;
   end Resolve_Entity_Name;

   -------------------
   -- Resolve_Entry --
   -------------------

   procedure Resolve_Entry (Entry_Name : Node_Id) is
      Loc    : constant Source_Ptr := Sloc (Entry_Name);
      Nam    : Entity_Id;
      New_N  : Node_Id;
      S      : Entity_Id;
      Tsk    : Entity_Id;
      E_Name : Node_Id;
      Index  : Node_Id;

      function Actual_Index_Type (E : Entity_Id) return Entity_Id;
      --  If the bounds of the entry family being called depend on task
      --  discriminants, build a new index subtype where a discriminant is
      --  replaced with the value of the discriminant of the target task.
      --  The target task is the prefix of the entry name in the call.

      -----------------------
      -- Actual_Index_Type --
      -----------------------

      function Actual_Index_Type (E : Entity_Id) return Entity_Id is
         Typ   : constant Entity_Id := Entry_Index_Type (E);
         Tsk   : constant Entity_Id := Scope (E);
         Lo    : constant Node_Id   := Type_Low_Bound  (Typ);
         Hi    : constant Node_Id   := Type_High_Bound (Typ);
         New_T : Entity_Id;

         function Actual_Discriminant_Ref (Bound : Node_Id) return Node_Id;
         --  If the bound is given by a discriminant, replace with a reference
         --  to the discriminant of the same name in the target task. If the
         --  entry name is the target of a requeue statement and the entry is
         --  in the current protected object, the bound to be used is the
         --  discriminal of the object (see Apply_Range_Checks for details of
         --  the transformation).

         -----------------------------
         -- Actual_Discriminant_Ref --
         -----------------------------

         function Actual_Discriminant_Ref (Bound : Node_Id) return Node_Id is
            Typ : constant Entity_Id := Etype (Bound);
            Ref : Node_Id;

         begin
            Remove_Side_Effects (Bound);

            if not Is_Entity_Name (Bound)
              or else Ekind (Entity (Bound)) /= E_Discriminant
            then
               return Bound;

            elsif Is_Protected_Type (Tsk)
              and then In_Open_Scopes (Tsk)
              and then Nkind (Parent (Entry_Name)) = N_Requeue_Statement
            then
               --  Note: here Bound denotes a discriminant of the corresponding
               --  record type tskV, whose discriminal is a formal of the
               --  init-proc tskVIP. What we want is the body discriminal,
               --  which is associated to the discriminant of the original
               --  concurrent type tsk.

               return New_Occurrence_Of
                        (Find_Body_Discriminal (Entity (Bound)), Loc);

            else
               Ref :=
                 Make_Selected_Component (Loc,
                   Prefix => New_Copy_Tree (Prefix (Prefix (Entry_Name))),
                   Selector_Name => New_Occurrence_Of (Entity (Bound), Loc));
               Analyze (Ref);
               Resolve (Ref, Typ);
               return Ref;
            end if;
         end Actual_Discriminant_Ref;

      --  Start of processing for Actual_Index_Type

      begin
         if not Has_Discriminants (Tsk)
           or else (not Is_Entity_Name (Lo) and then not Is_Entity_Name (Hi))
         then
            return Entry_Index_Type (E);

         else
            New_T := Create_Itype (Ekind (Typ), Parent (Entry_Name));
            Set_Etype        (New_T, Base_Type (Typ));
            Set_Size_Info    (New_T, Typ);
            Set_RM_Size      (New_T, RM_Size (Typ));
            Set_Scalar_Range (New_T,
              Make_Range (Sloc (Entry_Name),
                Low_Bound  => Actual_Discriminant_Ref (Lo),
                High_Bound => Actual_Discriminant_Ref (Hi)));

            return New_T;
         end if;
      end Actual_Index_Type;

   --  Start of processing for Resolve_Entry

   begin
      --  Find name of entry being called, and resolve prefix of name with its
      --  own type. The prefix can be overloaded, and the name and signature of
      --  the entry must be taken into account.

      if Nkind (Entry_Name) = N_Indexed_Component then

         --  Case of dealing with entry family within the current tasks

         E_Name := Prefix (Entry_Name);

      else
         E_Name := Entry_Name;
      end if;

      if Is_Entity_Name (E_Name) then

         --  Entry call to an entry (or entry family) in the current task. This
         --  is legal even though the task will deadlock. Rewrite as call to
         --  current task.

         --  This can also be a call to an entry in an enclosing task. If this
         --  is a single task, we have to retrieve its name, because the scope
         --  of the entry is the task type, not the object. If the enclosing
         --  task is a task type, the identity of the task is given by its own
         --  self variable.

         --  Finally this can be a requeue on an entry of the same task or
         --  protected object.

         S := Scope (Entity (E_Name));

         for J in reverse 0 .. Scope_Stack.Last loop
            if Is_Task_Type (Scope_Stack.Table (J).Entity)
              and then not Comes_From_Source (S)
            then
               --  S is an enclosing task or protected object. The concurrent
               --  declaration has been converted into a type declaration, and
               --  the object itself has an object declaration that follows
               --  the type in the same declarative part.

               Tsk := Next_Entity (S);
               while Etype (Tsk) /= S loop
                  Next_Entity (Tsk);
               end loop;

               S := Tsk;
               exit;

            elsif S = Scope_Stack.Table (J).Entity then

               --  Call to current task. Will be transformed into call to Self

               exit;

            end if;
         end loop;

         New_N :=
           Make_Selected_Component (Loc,
             Prefix => New_Occurrence_Of (S, Loc),
             Selector_Name =>
               New_Occurrence_Of (Entity (E_Name), Loc));
         Rewrite (E_Name, New_N);
         Analyze (E_Name);

      elsif Nkind (Entry_Name) = N_Selected_Component
        and then Is_Overloaded (Prefix (Entry_Name))
      then
         --  Use the entry name (which must be unique at this point) to find
         --  the prefix that returns the corresponding task/protected type.

         declare
            Pref : constant Node_Id := Prefix (Entry_Name);
            Ent  : constant Entity_Id := Entity (Selector_Name (Entry_Name));
            I    : Interp_Index;
            It   : Interp;

         begin
            Get_First_Interp (Pref, I, It);
            while Present (It.Typ) loop
               if Scope (Ent) = It.Typ then
                  Set_Etype (Pref, It.Typ);
                  exit;
               end if;

               Get_Next_Interp (I, It);
            end loop;
         end;
      end if;

      if Nkind (Entry_Name) = N_Selected_Component then
         Resolve (Prefix (Entry_Name));

      else pragma Assert (Nkind (Entry_Name) = N_Indexed_Component);
         Nam := Entity (Selector_Name (Prefix (Entry_Name)));
         Resolve (Prefix (Prefix (Entry_Name)));
         Index := First (Expressions (Entry_Name));
         Resolve (Index, Entry_Index_Type (Nam));

         --  Generate a reference for the index when it denotes an entity

         if Is_Entity_Name (Index) then
            Generate_Reference (Entity (Index), Nam);
         end if;

         --  Up to this point the expression could have been the actual in a
         --  simple entry call, and be given by a named association.

         if Nkind (Index) = N_Parameter_Association then
            Error_Msg_N ("expect expression for entry index", Index);
         else
            Apply_Range_Check (Index, Actual_Index_Type (Nam));
         end if;
      end if;
   end Resolve_Entry;

   ------------------------
   -- Resolve_Entry_Call --
   ------------------------

   procedure Resolve_Entry_Call (N : Node_Id; Typ : Entity_Id) is
      Entry_Name : constant Node_Id    := Name (N);
      Loc        : constant Source_Ptr := Sloc (Entry_Name);

      Nam      : Entity_Id;
      Norm_OK  : Boolean;
      Obj      : Node_Id;
      Was_Over : Boolean;

   begin
      --  We kill all checks here, because it does not seem worth the effort to
      --  do anything better, an entry call is a big operation.

      Kill_All_Checks;

      --  Processing of the name is similar for entry calls and protected
      --  operation calls. Once the entity is determined, we can complete
      --  the resolution of the actuals.

      --  The selector may be overloaded, in the case of a protected object
      --  with overloaded functions. The type of the context is used for
      --  resolution.

      if Nkind (Entry_Name) = N_Selected_Component
        and then Is_Overloaded (Selector_Name (Entry_Name))
        and then Typ /= Standard_Void_Type
      then
         declare
            I  : Interp_Index;
            It : Interp;

         begin
            Get_First_Interp (Selector_Name (Entry_Name), I, It);
            while Present (It.Typ) loop
               if Covers (Typ, It.Typ) then
                  Set_Entity (Selector_Name (Entry_Name), It.Nam);
                  Set_Etype  (Entry_Name, It.Typ);

                  Generate_Reference (It.Typ, N, ' ');
               end if;

               Get_Next_Interp (I, It);
            end loop;
         end;
      end if;

      Resolve_Entry (Entry_Name);

      if Nkind (Entry_Name) = N_Selected_Component then

         --  Simple entry or protected operation call

         Nam := Entity (Selector_Name (Entry_Name));
         Obj := Prefix (Entry_Name);

         if Is_Subprogram (Nam) then
            Check_For_Eliminated_Subprogram (Entry_Name, Nam);
         end if;

         Was_Over := Is_Overloaded (Selector_Name (Entry_Name));

      else pragma Assert (Nkind (Entry_Name) = N_Indexed_Component);

         --  Call to member of entry family

         Nam := Entity (Selector_Name (Prefix (Entry_Name)));
         Obj := Prefix (Prefix (Entry_Name));
         Was_Over := Is_Overloaded (Selector_Name (Prefix (Entry_Name)));
      end if;

      --  We cannot in general check the maximum depth of protected entry calls
      --  at compile time. But we can tell that any protected entry call at all
      --  violates a specified nesting depth of zero.

      if Is_Protected_Type (Scope (Nam)) then
         Check_Restriction (Max_Entry_Queue_Length, N);
      end if;

      --  Use context type to disambiguate a protected function that can be
      --  called without actuals and that returns an array type, and where the
      --  argument list may be an indexing of the returned value.

      if Ekind (Nam) = E_Function
        and then Needs_No_Actuals (Nam)
        and then Present (Parameter_Associations (N))
        and then
          ((Is_Array_Type (Etype (Nam))
             and then Covers (Typ, Component_Type (Etype (Nam))))

            or else (Is_Access_Type (Etype (Nam))
                      and then Is_Array_Type (Designated_Type (Etype (Nam)))
                      and then
                        Covers
                         (Typ,
                          Component_Type (Designated_Type (Etype (Nam))))))
      then
         declare
            Index_Node : Node_Id;

         begin
            Index_Node :=
              Make_Indexed_Component (Loc,
                Prefix =>
                  Make_Function_Call (Loc, Name => Relocate_Node (Entry_Name)),
                Expressions => Parameter_Associations (N));

            --  Since we are correcting a node classification error made by the
            --  parser, we call Replace rather than Rewrite.

            Replace (N, Index_Node);
            Set_Etype (Prefix (N), Etype (Nam));
            Set_Etype (N, Typ);
            Resolve_Indexed_Component (N, Typ);
            return;
         end;
      end if;

      if Ekind_In (Nam, E_Entry, E_Entry_Family)
        and then Present (Contract_Wrapper (Nam))
        and then Current_Scope /= Contract_Wrapper (Nam)
      then
         --  Note the entity being called before rewriting the call, so that
         --  it appears used at this point.

         Generate_Reference (Nam, Entry_Name, 'r');

         --  Rewrite as call to the precondition wrapper, adding the task
         --  object to the list of actuals. If the call is to a member of an
         --  entry family, include the index as well.

         declare
            New_Call    : Node_Id;
            New_Actuals : List_Id;

         begin
            New_Actuals := New_List (Obj);

            if Nkind (Entry_Name) = N_Indexed_Component then
               Append_To (New_Actuals,
                 New_Copy_Tree (First (Expressions (Entry_Name))));
            end if;

            Append_List (Parameter_Associations (N), New_Actuals);
            New_Call :=
              Make_Procedure_Call_Statement (Loc,
                Name                   =>
                  New_Occurrence_Of (Contract_Wrapper (Nam), Loc),
                Parameter_Associations => New_Actuals);
            Rewrite (N, New_Call);

            --  Preanalyze and resolve new call. Current procedure is called
            --  from Resolve_Call, after which expansion will take place.

            Preanalyze_And_Resolve (N);
            return;
         end;
      end if;

      --  The operation name may have been overloaded. Order the actuals
      --  according to the formals of the resolved entity, and set the return
      --  type to that of the operation.

      if Was_Over then
         Normalize_Actuals (N, Nam, False, Norm_OK);
         pragma Assert (Norm_OK);
         Set_Etype (N, Etype (Nam));

         --  Reset the Is_Overloaded flag, since resolution is now completed

         --  Simple entry call

         if Nkind (Entry_Name) = N_Selected_Component then
            Set_Is_Overloaded (Selector_Name (Entry_Name), False);

         --  Call to a member of an entry family

         else pragma Assert (Nkind (Entry_Name) = N_Indexed_Component);
            Set_Is_Overloaded (Selector_Name (Prefix (Entry_Name)), False);
         end if;
      end if;

      Resolve_Actuals (N, Nam);
      Check_Internal_Protected_Use (N, Nam);

      --  Create a call reference to the entry

      Generate_Reference (Nam, Entry_Name, 's');

      if Ekind_In (Nam, E_Entry, E_Entry_Family) then
         Check_Potentially_Blocking_Operation (N);
      end if;

      --  Verify that a procedure call cannot masquerade as an entry
      --  call where an entry call is expected.

      if Ekind (Nam) = E_Procedure then
         if Nkind (Parent (N)) = N_Entry_Call_Alternative
           and then N = Entry_Call_Statement (Parent (N))
         then
            Error_Msg_N ("entry call required in select statement", N);

         elsif Nkind (Parent (N)) = N_Triggering_Alternative
           and then N = Triggering_Statement (Parent (N))
         then
            Error_Msg_N ("triggering statement cannot be procedure call", N);

         elsif Ekind (Scope (Nam)) = E_Task_Type
           and then not In_Open_Scopes (Scope (Nam))
         then
            Error_Msg_N ("task has no entry with this name", Entry_Name);
         end if;
      end if;

      --  After resolution, entry calls and protected procedure calls are
      --  changed into entry calls, for expansion. The structure of the node
      --  does not change, so it can safely be done in place. Protected
      --  function calls must keep their structure because they are
      --  subexpressions.

      if Ekind (Nam) /= E_Function then

         --  A protected operation that is not a function may modify the
         --  corresponding object, and cannot apply to a constant. If this
         --  is an internal call, the prefix is the type itself.

         if Is_Protected_Type (Scope (Nam))
           and then not Is_Variable (Obj)
           and then (not Is_Entity_Name (Obj)
                       or else not Is_Type (Entity (Obj)))
         then
            Error_Msg_N
              ("prefix of protected procedure or entry call must be variable",
               Entry_Name);
         end if;

         declare
            Entry_Call : Node_Id;

         begin
            Entry_Call :=
              Make_Entry_Call_Statement (Loc,
                Name                   => Entry_Name,
                Parameter_Associations => Parameter_Associations (N));

            --  Inherit relevant attributes from the original call

            Set_First_Named_Actual
              (Entry_Call, First_Named_Actual (N));

            Set_Is_Elaboration_Checks_OK_Node
              (Entry_Call, Is_Elaboration_Checks_OK_Node (N));

            Set_Is_Elaboration_Warnings_OK_Node
              (Entry_Call, Is_Elaboration_Warnings_OK_Node (N));

            Set_Is_SPARK_Mode_On_Node
              (Entry_Call, Is_SPARK_Mode_On_Node (N));

            Rewrite (N, Entry_Call);
            Set_Analyzed (N, True);
         end;

      --  Protected functions can return on the secondary stack, in which case
      --  we must trigger the transient scope mechanism.

      elsif Expander_Active
        and then Requires_Transient_Scope (Etype (Nam))
      then
         Establish_Transient_Scope (N, Manage_Sec_Stack => True);
      end if;
   end Resolve_Entry_Call;

   -------------------------
   -- Resolve_Equality_Op --
   -------------------------

   --  Both arguments must have the same type, and the boolean context does
   --  not participate in the resolution. The first pass verifies that the
   --  interpretation is not ambiguous, and the type of the left argument is
   --  correctly set, or is Any_Type in case of ambiguity. If both arguments
   --  are strings or aggregates, allocators, or Null, they are ambiguous even
   --  though they carry a single (universal) type. Diagnose this case here.

   procedure Resolve_Equality_Op (N : Node_Id; Typ : Entity_Id) is
      L : constant Node_Id   := Left_Opnd (N);
      R : constant Node_Id   := Right_Opnd (N);
      T : Entity_Id := Find_Unique_Type (L, R);

      procedure Check_If_Expression (Cond : Node_Id);
      --  The resolution rule for if expressions requires that each such must
      --  have a unique type. This means that if several dependent expressions
      --  are of a non-null anonymous access type, and the context does not
      --  impose an expected type (as can be the case in an equality operation)
      --  the expression must be rejected.

      procedure Explain_Redundancy (N : Node_Id);
      --  Attempt to explain the nature of a redundant comparison with True. If
      --  the expression N is too complex, this routine issues a general error
      --  message.

      function Find_Unique_Access_Type return Entity_Id;
      --  In the case of allocators and access attributes, the context must
      --  provide an indication of the specific access type to be used. If
      --  one operand is of such a "generic" access type, check whether there
      --  is a specific visible access type that has the same designated type.
      --  This is semantically dubious, and of no interest to any real code,
      --  but c48008a makes it all worthwhile.

      -------------------------
      -- Check_If_Expression --
      -------------------------

      procedure Check_If_Expression (Cond : Node_Id) is
         Then_Expr : Node_Id;
         Else_Expr : Node_Id;

      begin
         if Nkind (Cond) = N_If_Expression then
            Then_Expr := Next (First (Expressions (Cond)));
            Else_Expr := Next (Then_Expr);

            if Nkind (Then_Expr) /= N_Null
              and then Nkind (Else_Expr) /= N_Null
            then
               Error_Msg_N ("cannot determine type of if expression", Cond);
            end if;
         end if;
      end Check_If_Expression;

      ------------------------
      -- Explain_Redundancy --
      ------------------------

      procedure Explain_Redundancy (N : Node_Id) is
         Error  : Name_Id;
         Val    : Node_Id;
         Val_Id : Entity_Id;

      begin
         Val := N;

         --  Strip the operand down to an entity

         loop
            if Nkind (Val) = N_Selected_Component then
               Val := Selector_Name (Val);
            else
               exit;
            end if;
         end loop;

         --  The construct denotes an entity

         if Is_Entity_Name (Val) and then Present (Entity (Val)) then
            Val_Id := Entity (Val);

            --  Do not generate an error message when the comparison is done
            --  against the enumeration literal Standard.True.

            if Ekind (Val_Id) /= E_Enumeration_Literal then

               --  Build a customized error message

               Name_Len := 0;
               Add_Str_To_Name_Buffer ("?r?");

               if Ekind (Val_Id) = E_Component then
                  Add_Str_To_Name_Buffer ("component ");

               elsif Ekind (Val_Id) = E_Constant then
                  Add_Str_To_Name_Buffer ("constant ");

               elsif Ekind (Val_Id) = E_Discriminant then
                  Add_Str_To_Name_Buffer ("discriminant ");

               elsif Is_Formal (Val_Id) then
                  Add_Str_To_Name_Buffer ("parameter ");

               elsif Ekind (Val_Id) = E_Variable then
                  Add_Str_To_Name_Buffer ("variable ");
               end if;

               Add_Str_To_Name_Buffer ("& is always True!");
               Error := Name_Find;

               Error_Msg_NE (Get_Name_String (Error), Val, Val_Id);
            end if;

         --  The construct is too complex to disect, issue a general message

         else
            Error_Msg_N ("?r?expression is always True!", Val);
         end if;
      end Explain_Redundancy;

      -----------------------------
      -- Find_Unique_Access_Type --
      -----------------------------

      function Find_Unique_Access_Type return Entity_Id is
         Acc : Entity_Id;
         E   : Entity_Id;
         S   : Entity_Id;

      begin
         if Ekind_In (Etype (R), E_Allocator_Type,
                                 E_Access_Attribute_Type)
         then
            Acc := Designated_Type (Etype (R));

         elsif Ekind_In (Etype (L), E_Allocator_Type,
                                    E_Access_Attribute_Type)
         then
            Acc := Designated_Type (Etype (L));
         else
            return Empty;
         end if;

         S := Current_Scope;
         while S /= Standard_Standard loop
            E := First_Entity (S);
            while Present (E) loop
               if Is_Type (E)
                 and then Is_Access_Type (E)
                 and then Ekind (E) /= E_Allocator_Type
                 and then Designated_Type (E) = Base_Type (Acc)
               then
                  return E;
               end if;

               Next_Entity (E);
            end loop;

            S := Scope (S);
         end loop;

         return Empty;
      end Find_Unique_Access_Type;

   --  Start of processing for Resolve_Equality_Op

   begin
      Set_Etype (N, Base_Type (Typ));
      Generate_Reference (T, N, ' ');

      if T = Any_Fixed then
         T := Unique_Fixed_Point_Type (L);
      end if;

      if T /= Any_Type then
         if T = Any_String    or else
            T = Any_Composite or else
            T = Any_Character
         then
            if T = Any_Character then
               Ambiguous_Character (L);
            else
               Error_Msg_N ("ambiguous operands for equality", N);
            end if;

            Set_Etype (N, Any_Type);
            return;

         elsif T = Any_Access
           or else Ekind_In (T, E_Allocator_Type, E_Access_Attribute_Type)
         then
            T := Find_Unique_Access_Type;

            if No (T) then
               Error_Msg_N ("ambiguous operands for equality", N);
               Set_Etype (N, Any_Type);
               return;
            end if;

         --  If expressions must have a single type, and if the context does
         --  not impose one the dependent expressions cannot be anonymous
         --  access types.

         --  Why no similar processing for case expressions???

         elsif Ada_Version >= Ada_2012
           and then Ekind_In (Etype (L), E_Anonymous_Access_Type,
                                         E_Anonymous_Access_Subprogram_Type)
           and then Ekind_In (Etype (R), E_Anonymous_Access_Type,
                                         E_Anonymous_Access_Subprogram_Type)
         then
            Check_If_Expression (L);
            Check_If_Expression (R);
         end if;

         Resolve (L, T);
         Resolve (R, T);

         --  In SPARK, equality operators = and /= for array types other than
         --  String are only defined when, for each index position, the
         --  operands have equal static bounds.

         if Is_Array_Type (T) then

            --  Protect call to Matching_Static_Array_Bounds to avoid costly
            --  operation if not needed.

            if Restriction_Check_Required (SPARK_05)
              and then Base_Type (T) /= Standard_String
              and then Base_Type (Etype (L)) = Base_Type (Etype (R))
              and then Etype (L) /= Any_Composite  --  or else L in error
              and then Etype (R) /= Any_Composite  --  or else R in error
              and then not Matching_Static_Array_Bounds (Etype (L), Etype (R))
            then
               Check_SPARK_05_Restriction
                 ("array types should have matching static bounds", N);
            end if;
         end if;

         --  If the unique type is a class-wide type then it will be expanded
         --  into a dispatching call to the predefined primitive. Therefore we
         --  check here for potential violation of such restriction.

         if Is_Class_Wide_Type (T) then
            Check_Restriction (No_Dispatching_Calls, N);
         end if;

         --  Only warn for redundant equality comparison to True for objects
         --  (e.g. "X = True") and operations (e.g. "(X < Y) = True"). For
         --  other expressions, it may be a matter of preference to write
         --  "Expr = True" or "Expr".

         if Warn_On_Redundant_Constructs
           and then Comes_From_Source (N)
           and then Comes_From_Source (R)
           and then Is_Entity_Name (R)
           and then Entity (R) = Standard_True
           and then
             ((Is_Entity_Name (L) and then Is_Object (Entity (L)))
                 or else
               Nkind (L) in N_Op)
         then
            Error_Msg_N -- CODEFIX
              ("?r?comparison with True is redundant!", N);
            Explain_Redundancy (Original_Node (R));
         end if;

         --  If the equality is overloaded and the operands have resolved
         --  properly, set the proper equality operator on the node. The
         --  current setting is the first one found during analysis, which
         --  is not necessarily the one to which the node has resolved.

         if Is_Overloaded (N) then
            declare
               I  : Interp_Index;
               It : Interp;

            begin
               Get_First_Interp (N, I, It);

               --  If the equality is user-defined, the type of the operands
               --  matches that of the formals. For a predefined operator,
               --  it is the scope that matters, given that the predefined
               --  equality has Any_Type formals. In either case the result
               --  type (most often Boolean) must match the context. The scope
               --  is either that of the type, if there is a generated equality
               --  (when there is an equality for the component type), or else
               --  Standard otherwise.

               while Present (It.Typ) loop
                  if Etype (It.Nam) = Typ
                    and then
                     (Etype (First_Entity (It.Nam)) = Etype (L)
                       or else Scope (It.Nam) = Standard_Standard
                       or else Scope (It.Nam) = Scope (T))
                  then
                     Set_Entity (N, It.Nam);

                     Set_Is_Overloaded (N, False);
                     exit;
                  end if;

                  Get_Next_Interp (I, It);
               end loop;

               --  If expansion is active and this is an inherited operation,
               --  replace it with its ancestor. This must not be done during
               --  preanalysis because the type may not be frozen yet, as when
               --  the context is a precondition or postcondition.

               if Present (Alias (Entity (N))) and then Expander_Active then
                  Set_Entity (N, Alias (Entity (N)));
               end if;
            end;
         end if;

         Check_Unset_Reference (L);
         Check_Unset_Reference (R);
         Generate_Operator_Reference (N, T);
         Check_Low_Bound_Tested (N);

         --  If this is an inequality, it may be the implicit inequality
         --  created for a user-defined operation, in which case the corres-
         --  ponding equality operation is not intrinsic, and the operation
         --  cannot be constant-folded. Else fold.

         if Nkind (N) = N_Op_Eq
           or else Comes_From_Source (Entity (N))
           or else Ekind (Entity (N)) = E_Operator
           or else Is_Intrinsic_Subprogram
                     (Corresponding_Equality (Entity (N)))
         then
            Analyze_Dimension (N);
            Eval_Relational_Op (N);

         elsif Nkind (N) = N_Op_Ne
           and then Is_Abstract_Subprogram (Entity (N))
         then
            Error_Msg_NE ("cannot call abstract subprogram &!", N, Entity (N));
         end if;

         --  Ada 2005: If one operand is an anonymous access type, convert the
         --  other operand to it, to ensure that the underlying types match in
         --  the back-end. Same for access_to_subprogram, and the conversion
         --  verifies that the types are subtype conformant.

         --  We apply the same conversion in the case one of the operands is a
         --  private subtype of the type of the other.

         --  Why the Expander_Active test here ???

         if Expander_Active
           and then
             (Ekind_In (T, E_Anonymous_Access_Type,
                           E_Anonymous_Access_Subprogram_Type)
               or else Is_Private_Type (T))
         then
            if Etype (L) /= T then
               Rewrite (L,
                 Make_Unchecked_Type_Conversion (Sloc (L),
                   Subtype_Mark => New_Occurrence_Of (T, Sloc (L)),
                   Expression   => Relocate_Node (L)));
               Analyze_And_Resolve (L, T);
            end if;

            if (Etype (R)) /= T then
               Rewrite (R,
                  Make_Unchecked_Type_Conversion (Sloc (R),
                    Subtype_Mark => New_Occurrence_Of (Etype (L), Sloc (R)),
                    Expression   => Relocate_Node (R)));
               Analyze_And_Resolve (R, T);
            end if;
         end if;
      end if;
   end Resolve_Equality_Op;

   ----------------------------------
   -- Resolve_Explicit_Dereference --
   ----------------------------------

   procedure Resolve_Explicit_Dereference (N : Node_Id; Typ : Entity_Id) is
      Loc   : constant Source_Ptr := Sloc (N);
      New_N : Node_Id;
      P     : constant Node_Id := Prefix (N);

      P_Typ : Entity_Id;
      --  The candidate prefix type, if overloaded

      I     : Interp_Index;
      It    : Interp;

   begin
      Check_Fully_Declared_Prefix (Typ, P);
      P_Typ := Empty;

      --  A useful optimization:  check whether the dereference denotes an
      --  element of a container, and if so rewrite it as a call to the
      --  corresponding Element function.

      --  Disabled for now, on advice of ARG. A more restricted form of the
      --  predicate might be acceptable ???

      --  if Is_Container_Element (N) then
      --     return;
      --  end if;

      if Is_Overloaded (P) then

         --  Use the context type to select the prefix that has the correct
         --  designated type. Keep the first match, which will be the inner-
         --  most.

         Get_First_Interp (P, I, It);

         while Present (It.Typ) loop
            if Is_Access_Type (It.Typ)
              and then Covers (Typ, Designated_Type (It.Typ))
            then
               if No (P_Typ) then
                  P_Typ := It.Typ;
               end if;

            --  Remove access types that do not match, but preserve access
            --  to subprogram interpretations, in case a further dereference
            --  is needed (see below).

            elsif Ekind (It.Typ) /= E_Access_Subprogram_Type then
               Remove_Interp (I);
            end if;

            Get_Next_Interp (I, It);
         end loop;

         if Present (P_Typ) then
            Resolve (P, P_Typ);
            Set_Etype (N, Designated_Type (P_Typ));

         else
            --  If no interpretation covers the designated type of the prefix,
            --  this is the pathological case where not all implementations of
            --  the prefix allow the interpretation of the node as a call. Now
            --  that the expected type is known, Remove other interpretations
            --  from prefix, rewrite it as a call, and resolve again, so that
            --  the proper call node is generated.

            Get_First_Interp (P, I, It);
            while Present (It.Typ) loop
               if Ekind (It.Typ) /= E_Access_Subprogram_Type then
                  Remove_Interp (I);
               end if;

               Get_Next_Interp (I, It);
            end loop;

            New_N :=
              Make_Function_Call (Loc,
                Name =>
                  Make_Explicit_Dereference (Loc,
                    Prefix => P),
                Parameter_Associations => New_List);

            Save_Interps (N, New_N);
            Rewrite (N, New_N);
            Analyze_And_Resolve (N, Typ);
            return;
         end if;

      --  If not overloaded, resolve P with its own type

      else
         Resolve (P);
      end if;

      --  If the prefix might be null, add an access check

      if Is_Access_Type (Etype (P))
        and then not Can_Never_Be_Null (Etype (P))
      then
         Apply_Access_Check (N);
      end if;

      --  If the designated type is a packed unconstrained array type, and the
      --  explicit dereference is not in the context of an attribute reference,
      --  then we must compute and set the actual subtype, since it is needed
      --  by Gigi. The reason we exclude the attribute case is that this is
      --  handled fine by Gigi, and in fact we use such attributes to build the
      --  actual subtype. We also exclude generated code (which builds actual
      --  subtypes directly if they are needed).

      if Is_Array_Type (Etype (N))
        and then Is_Packed (Etype (N))
        and then not Is_Constrained (Etype (N))
        and then Nkind (Parent (N)) /= N_Attribute_Reference
        and then Comes_From_Source (N)
      then
         Set_Etype (N, Get_Actual_Subtype (N));
      end if;

      Analyze_Dimension (N);

      --  Note: No Eval processing is required for an explicit dereference,
      --  because such a name can never be static.

   end Resolve_Explicit_Dereference;

   -------------------------------------
   -- Resolve_Expression_With_Actions --
   -------------------------------------

   procedure Resolve_Expression_With_Actions (N : Node_Id; Typ : Entity_Id) is
   begin
      Set_Etype (N, Typ);

      --  If N has no actions, and its expression has been constant folded,
      --  then rewrite N as just its expression. Note, we can't do this in
      --  the general case of Is_Empty_List (Actions (N)) as this would cause
      --  Expression (N) to be expanded again.

      if Is_Empty_List (Actions (N))
        and then Compile_Time_Known_Value (Expression (N))
      then
         Rewrite (N, Expression (N));
      end if;
   end Resolve_Expression_With_Actions;

   ----------------------------------
   -- Resolve_Generalized_Indexing --
   ----------------------------------

   procedure Resolve_Generalized_Indexing (N : Node_Id; Typ : Entity_Id) is
      Indexing : constant Node_Id := Generalized_Indexing (N);
      Call     : Node_Id;
      Indexes  : List_Id;
      Pref     : Node_Id;

   begin
      --  In ASIS mode, propagate the information about the indexes back to
      --  to the original indexing node. The generalized indexing is either
      --  a function call, or a dereference of one. The actuals include the
      --  prefix of the original node, which is the container expression.

      if ASIS_Mode then
         Resolve (Indexing, Typ);
         Set_Etype  (N, Etype (Indexing));
         Set_Is_Overloaded (N, False);

         Call := Indexing;
         while Nkind_In (Call, N_Explicit_Dereference, N_Selected_Component)
         loop
            Call := Prefix (Call);
         end loop;

         if Nkind (Call) = N_Function_Call then
            Indexes := New_Copy_List (Parameter_Associations (Call));
            Pref := Remove_Head (Indexes);
            Set_Expressions (N, Indexes);

            --  If expression is to be reanalyzed, reset Generalized_Indexing
            --  to recreate call node, as is the case when the expression is
            --  part of an expression function.

            if In_Spec_Expression then
               Set_Generalized_Indexing (N, Empty);
            end if;

            Set_Prefix (N, Pref);
         end if;

      else
         Rewrite (N, Indexing);
         Resolve (N, Typ);
      end if;
   end Resolve_Generalized_Indexing;

   ---------------------------
   -- Resolve_If_Expression --
   ---------------------------

   procedure Resolve_If_Expression (N : Node_Id; Typ : Entity_Id) is
      procedure Apply_Check (Expr : Node_Id);
      --  When a dependent expression is of a subtype different from
      --  the context subtype, then insert a qualification to ensure
      --  the generation of a constraint check. This was previously
      --  for scalar types. For array types apply a length check, given
      --  that the context in general allows sliding, while a qualified
      --  expression forces equality of bounds.

      -----------------
      -- Apply_Check --
      -----------------

      procedure Apply_Check (Expr : Node_Id) is
         Expr_Typ : constant Entity_Id  := Etype (Expr);
         Loc      : constant Source_Ptr := Sloc (Expr);

      begin
         if Expr_Typ = Typ
           or else Is_Tagged_Type (Typ)
           or else Is_Access_Type (Typ)
           or else not Is_Constrained (Typ)
           or else Inside_A_Generic
         then
            null;

         elsif Is_Array_Type (Typ) then
            Apply_Length_Check (Expr, Typ);

         else
            Rewrite (Expr,
              Make_Qualified_Expression (Loc,
                Subtype_Mark => New_Occurrence_Of (Typ, Loc),
                Expression   => Relocate_Node (Expr)));

            Analyze_And_Resolve (Expr, Typ);
         end if;
      end Apply_Check;

      --  Local variables

      Condition : constant Node_Id := First (Expressions (N));
      Else_Expr : Node_Id;
      Then_Expr : Node_Id;

   --  Start of processing for Resolve_If_Expression

   begin
      --  Defend against malformed expressions

      if No (Condition) then
         return;
      end if;

      Then_Expr := Next (Condition);

      if No (Then_Expr) then
         return;
      end if;

      Else_Expr := Next (Then_Expr);

      Resolve (Condition, Any_Boolean);
      Resolve (Then_Expr, Typ);
      Apply_Check (Then_Expr);

      --  If ELSE expression present, just resolve using the determined type
      --  If type is universal, resolve to any member of the class.

      if Present (Else_Expr) then
         if Typ = Universal_Integer then
            Resolve (Else_Expr, Any_Integer);

         elsif Typ = Universal_Real then
            Resolve (Else_Expr, Any_Real);

         else
            Resolve (Else_Expr, Typ);
         end if;

         Apply_Check (Else_Expr);

         --  Apply RM 4.5.7 (17/3): whether the expression is statically or
         --  dynamically tagged must be known statically.

         if Is_Tagged_Type (Typ) and then not Is_Class_Wide_Type (Typ) then
            if Is_Dynamically_Tagged (Then_Expr) /=
               Is_Dynamically_Tagged (Else_Expr)
            then
               Error_Msg_N ("all or none of the dependent expressions "
                            & "can be dynamically tagged", N);
            end if;
         end if;

      --  If no ELSE expression is present, root type must be Standard.Boolean
      --  and we provide a Standard.True result converted to the appropriate
      --  Boolean type (in case it is a derived boolean type).

      elsif Root_Type (Typ) = Standard_Boolean then
         Else_Expr :=
           Convert_To (Typ, New_Occurrence_Of (Standard_True, Sloc (N)));
         Analyze_And_Resolve (Else_Expr, Typ);
         Append_To (Expressions (N), Else_Expr);

      else
         Error_Msg_N ("can only omit ELSE expression in Boolean case", N);
         Append_To (Expressions (N), Error);
      end if;

      Set_Etype (N, Typ);

      if not Error_Posted (N) then
         Eval_If_Expression (N);
      end if;

      Analyze_Dimension (N);
   end Resolve_If_Expression;

   -------------------------------
   -- Resolve_Indexed_Component --
   -------------------------------

   procedure Resolve_Indexed_Component (N : Node_Id; Typ : Entity_Id) is
      Name       : constant Node_Id := Prefix  (N);
      Expr       : Node_Id;
      Array_Type : Entity_Id := Empty; -- to prevent junk warning
      Index      : Node_Id;

   begin
      if Present (Generalized_Indexing (N)) then
         Resolve_Generalized_Indexing (N, Typ);
         return;
      end if;

      if Is_Overloaded (Name) then

         --  Use the context type to select the prefix that yields the correct
         --  component type.

         declare
            I     : Interp_Index;
            It    : Interp;
            I1    : Interp_Index := 0;
            P     : constant Node_Id := Prefix (N);
            Found : Boolean := False;

         begin
            Get_First_Interp (P, I, It);
            while Present (It.Typ) loop
               if (Is_Array_Type (It.Typ)
                     and then Covers (Typ, Component_Type (It.Typ)))
                 or else (Is_Access_Type (It.Typ)
                            and then Is_Array_Type (Designated_Type (It.Typ))
                            and then
                              Covers
                                (Typ,
                                 Component_Type (Designated_Type (It.Typ))))
               then
                  if Found then
                     It := Disambiguate (P, I1, I, Any_Type);

                     if It = No_Interp then
                        Error_Msg_N ("ambiguous prefix for indexing",  N);
                        Set_Etype (N, Typ);
                        return;

                     else
                        Found := True;
                        Array_Type := It.Typ;
                        I1 := I;
                     end if;

                  else
                     Found := True;
                     Array_Type := It.Typ;
                     I1 := I;
                  end if;
               end if;

               Get_Next_Interp (I, It);
            end loop;
         end;

      else
         Array_Type := Etype (Name);
      end if;

      Resolve (Name, Array_Type);
      Array_Type := Get_Actual_Subtype_If_Available (Name);

      --  If prefix is access type, dereference to get real array type.
      --  Note: we do not apply an access check because the expander always
      --  introduces an explicit dereference, and the check will happen there.

      if Is_Access_Type (Array_Type) then
         Array_Type := Designated_Type (Array_Type);
      end if;

      --  If name was overloaded, set component type correctly now
      --  If a misplaced call to an entry family (which has no index types)
      --  return. Error will be diagnosed from calling context.

      if Is_Array_Type (Array_Type) then
         Set_Etype (N, Component_Type (Array_Type));
      else
         return;
      end if;

      Index := First_Index (Array_Type);
      Expr  := First (Expressions (N));

      --  The prefix may have resolved to a string literal, in which case its
      --  etype has a special representation. This is only possible currently
      --  if the prefix is a static concatenation, written in functional
      --  notation.

      if Ekind (Array_Type) = E_String_Literal_Subtype then
         Resolve (Expr, Standard_Positive);

      else
         while Present (Index) and Present (Expr) loop
            Resolve (Expr, Etype (Index));
            Check_Unset_Reference (Expr);

            if Is_Scalar_Type (Etype (Expr)) then
               Apply_Scalar_Range_Check (Expr, Etype (Index));
            else
               Apply_Range_Check (Expr, Get_Actual_Subtype (Index));
            end if;

            Next_Index (Index);
            Next (Expr);
         end loop;
      end if;

      Analyze_Dimension (N);

      --  Do not generate the warning on suspicious index if we are analyzing
      --  package Ada.Tags; otherwise we will report the warning with the
      --  Prims_Ptr field of the dispatch table.

      if Scope (Etype (Prefix (N))) = Standard_Standard
        or else not
          Is_RTU (Cunit_Entity (Get_Source_Unit (Etype (Prefix (N)))),
                  Ada_Tags)
      then
         Warn_On_Suspicious_Index (Name, First (Expressions (N)));
         Eval_Indexed_Component (N);
      end if;

      --  If the array type is atomic, and the component is not atomic, then
      --  this is worth a warning, since we have a situation where the access
      --  to the component may cause extra read/writes of the atomic array
      --  object, or partial word accesses, which could be unexpected.

      if Nkind (N) = N_Indexed_Component
        and then Is_Atomic_Ref_With_Address (N)
        and then not (Has_Atomic_Components (Array_Type)
                       or else (Is_Entity_Name (Prefix (N))
                                 and then Has_Atomic_Components
                                            (Entity (Prefix (N)))))
        and then not Is_Atomic (Component_Type (Array_Type))
      then
         Error_Msg_N
           ("??access to non-atomic component of atomic array", Prefix (N));
         Error_Msg_N
           ("??\may cause unexpected accesses to atomic object", Prefix (N));
      end if;
   end Resolve_Indexed_Component;

   -----------------------------
   -- Resolve_Integer_Literal --
   -----------------------------

   procedure Resolve_Integer_Literal (N : Node_Id; Typ : Entity_Id) is
   begin
      Set_Etype (N, Typ);
      Eval_Integer_Literal (N);
   end Resolve_Integer_Literal;

   --------------------------------
   -- Resolve_Intrinsic_Operator --
   --------------------------------

   procedure Resolve_Intrinsic_Operator  (N : Node_Id; Typ : Entity_Id) is
      Btyp : constant Entity_Id := Base_Type (Underlying_Type (Typ));
      Op   : Entity_Id;
      Arg1 : Node_Id;
      Arg2 : Node_Id;

      function Convert_Operand (Opnd : Node_Id) return Node_Id;
      --  If the operand is a literal, it cannot be the expression in a
      --  conversion. Use a qualified expression instead.

      ---------------------
      -- Convert_Operand --
      ---------------------

      function Convert_Operand (Opnd : Node_Id) return Node_Id is
         Loc : constant Source_Ptr := Sloc (Opnd);
         Res : Node_Id;

      begin
         if Nkind_In (Opnd, N_Integer_Literal, N_Real_Literal) then
            Res :=
              Make_Qualified_Expression (Loc,
                Subtype_Mark => New_Occurrence_Of (Btyp, Loc),
                Expression   => Relocate_Node (Opnd));
            Analyze (Res);

         else
            Res := Unchecked_Convert_To (Btyp, Opnd);
         end if;

         return Res;
      end Convert_Operand;

   --  Start of processing for Resolve_Intrinsic_Operator

   begin
      --  We must preserve the original entity in a generic setting, so that
      --  the legality of the operation can be verified in an instance.

      if not Expander_Active then
         return;
      end if;

      Op := Entity (N);
      while Scope (Op) /= Standard_Standard loop
         Op := Homonym (Op);
         pragma Assert (Present (Op));
      end loop;

      Set_Entity (N, Op);
      Set_Is_Overloaded (N, False);

      --  If the result or operand types are private, rewrite with unchecked
      --  conversions on the operands and the result, to expose the proper
      --  underlying numeric type.

      if Is_Private_Type (Typ)
        or else Is_Private_Type (Etype (Left_Opnd (N)))
        or else Is_Private_Type (Etype (Right_Opnd (N)))
      then
         Arg1 := Convert_Operand (Left_Opnd (N));

         if Nkind (N) = N_Op_Expon then
            Arg2 := Unchecked_Convert_To (Standard_Integer, Right_Opnd (N));
         else
            Arg2 := Convert_Operand (Right_Opnd (N));
         end if;

         if Nkind (Arg1) = N_Type_Conversion then
            Save_Interps (Left_Opnd (N),  Expression (Arg1));
         end if;

         if Nkind (Arg2) = N_Type_Conversion then
            Save_Interps (Right_Opnd (N), Expression (Arg2));
         end if;

         Set_Left_Opnd  (N, Arg1);
         Set_Right_Opnd (N, Arg2);

         Set_Etype (N, Btyp);
         Rewrite (N, Unchecked_Convert_To (Typ, N));
         Resolve (N, Typ);

      elsif Typ /= Etype (Left_Opnd (N))
        or else Typ /= Etype (Right_Opnd (N))
      then
         --  Add explicit conversion where needed, and save interpretations in
         --  case operands are overloaded.

         Arg1 := Convert_To (Typ, Left_Opnd  (N));
         Arg2 := Convert_To (Typ, Right_Opnd (N));

         if Nkind (Arg1) = N_Type_Conversion then
            Save_Interps (Left_Opnd (N), Expression (Arg1));
         else
            Save_Interps (Left_Opnd (N), Arg1);
         end if;

         if Nkind (Arg2) = N_Type_Conversion then
            Save_Interps (Right_Opnd (N), Expression (Arg2));
         else
            Save_Interps (Right_Opnd (N), Arg2);
         end if;

         Rewrite (Left_Opnd  (N), Arg1);
         Rewrite (Right_Opnd (N), Arg2);
         Analyze (Arg1);
         Analyze (Arg2);
         Resolve_Arithmetic_Op (N, Typ);

      else
         Resolve_Arithmetic_Op (N, Typ);
      end if;
   end Resolve_Intrinsic_Operator;

   --------------------------------------
   -- Resolve_Intrinsic_Unary_Operator --
   --------------------------------------

   procedure Resolve_Intrinsic_Unary_Operator
     (N   : Node_Id;
      Typ : Entity_Id)
   is
      Btyp : constant Entity_Id := Base_Type (Underlying_Type (Typ));
      Op   : Entity_Id;
      Arg2 : Node_Id;

   begin
      Op := Entity (N);
      while Scope (Op) /= Standard_Standard loop
         Op := Homonym (Op);
         pragma Assert (Present (Op));
      end loop;

      Set_Entity (N, Op);

      if Is_Private_Type (Typ) then
         Arg2 := Unchecked_Convert_To (Btyp, Right_Opnd (N));
         Save_Interps (Right_Opnd (N), Expression (Arg2));

         Set_Right_Opnd (N, Arg2);

         Set_Etype (N, Btyp);
         Rewrite (N, Unchecked_Convert_To (Typ, N));
         Resolve (N, Typ);

      else
         Resolve_Unary_Op (N, Typ);
      end if;
   end Resolve_Intrinsic_Unary_Operator;

   ------------------------
   -- Resolve_Logical_Op --
   ------------------------

   procedure Resolve_Logical_Op (N : Node_Id; Typ : Entity_Id) is
      B_Typ : Entity_Id;

   begin
      Check_No_Direct_Boolean_Operators (N);

      --  Predefined operations on scalar types yield the base type. On the
      --  other hand, logical operations on arrays yield the type of the
      --  arguments (and the context).

      if Is_Array_Type (Typ) then
         B_Typ := Typ;
      else
         B_Typ := Base_Type (Typ);
      end if;

      --  The following test is required because the operands of the operation
      --  may be literals, in which case the resulting type appears to be
      --  compatible with a signed integer type, when in fact it is compatible
      --  only with modular types. If the context itself is universal, the
      --  operation is illegal.

      if not Valid_Boolean_Arg (Typ) then
         Error_Msg_N ("invalid context for logical operation", N);
         Set_Etype (N, Any_Type);
         return;

      elsif Typ = Any_Modular then
         Error_Msg_N
           ("no modular type available in this context", N);
         Set_Etype (N, Any_Type);
         return;

      elsif Is_Modular_Integer_Type (Typ)
        and then Etype (Left_Opnd (N)) = Universal_Integer
        and then Etype (Right_Opnd (N)) = Universal_Integer
      then
         Check_For_Visible_Operator (N, B_Typ);
      end if;

      --  Replace AND by AND THEN, or OR by OR ELSE, if Short_Circuit_And_Or
      --  is active and the result type is standard Boolean (do not mess with
      --  ops that return a nonstandard Boolean type, because something strange
      --  is going on).

      --  Note: you might expect this replacement to be done during expansion,
      --  but that doesn't work, because when the pragma Short_Circuit_And_Or
      --  is used, no part of the right operand of an "and" or "or" operator
      --  should be executed if the left operand would short-circuit the
      --  evaluation of the corresponding "and then" or "or else". If we left
      --  the replacement to expansion time, then run-time checks associated
      --  with such operands would be evaluated unconditionally, due to being
      --  before the condition prior to the rewriting as short-circuit forms
      --  during expansion.

      if Short_Circuit_And_Or
        and then B_Typ = Standard_Boolean
        and then Nkind_In (N, N_Op_And, N_Op_Or)
      then
         --  Mark the corresponding putative SCO operator as truly a logical
         --  (and short-circuit) operator.

         if Generate_SCO and then Comes_From_Source (N) then
            Set_SCO_Logical_Operator (N);
         end if;

         if Nkind (N) = N_Op_And then
            Rewrite (N,
              Make_And_Then (Sloc (N),
                Left_Opnd  => Relocate_Node (Left_Opnd (N)),
                Right_Opnd => Relocate_Node (Right_Opnd (N))));
            Analyze_And_Resolve (N, B_Typ);

         --  Case of OR changed to OR ELSE

         else
            Rewrite (N,
              Make_Or_Else (Sloc (N),
                Left_Opnd  => Relocate_Node (Left_Opnd (N)),
                Right_Opnd => Relocate_Node (Right_Opnd (N))));
            Analyze_And_Resolve (N, B_Typ);
         end if;

         --  Return now, since analysis of the rewritten ops will take care of
         --  other reference bookkeeping and expression folding.

         return;
      end if;

      Resolve (Left_Opnd (N), B_Typ);
      Resolve (Right_Opnd (N), B_Typ);

      Check_Unset_Reference (Left_Opnd  (N));
      Check_Unset_Reference (Right_Opnd (N));

      Set_Etype (N, B_Typ);
      Generate_Operator_Reference (N, B_Typ);
      Eval_Logical_Op (N);

      --  In SPARK, logical operations AND, OR and XOR for arrays are defined
      --  only when both operands have same static lower and higher bounds. Of
      --  course the types have to match, so only check if operands are
      --  compatible and the node itself has no errors.

      if Is_Array_Type (B_Typ)
        and then Nkind (N) in N_Binary_Op
      then
         declare
            Left_Typ  : constant Node_Id := Etype (Left_Opnd (N));
            Right_Typ : constant Node_Id := Etype (Right_Opnd (N));

         begin
            --  Protect call to Matching_Static_Array_Bounds to avoid costly
            --  operation if not needed.

            if Restriction_Check_Required (SPARK_05)
              and then Base_Type (Left_Typ) = Base_Type (Right_Typ)
              and then Left_Typ /= Any_Composite  --  or Left_Opnd in error
              and then Right_Typ /= Any_Composite  --  or Right_Opnd in error
              and then not Matching_Static_Array_Bounds (Left_Typ, Right_Typ)
            then
               Check_SPARK_05_Restriction
                 ("array types should have matching static bounds", N);
            end if;
         end;
      end if;
   end Resolve_Logical_Op;

   ---------------------------
   -- Resolve_Membership_Op --
   ---------------------------

   --  The context can only be a boolean type, and does not determine the
   --  arguments. Arguments should be unambiguous, but the preference rule for
   --  universal types applies.

   procedure Resolve_Membership_Op (N : Node_Id; Typ : Entity_Id) is
      pragma Warnings (Off, Typ);

      L : constant Node_Id := Left_Opnd  (N);
      R : constant Node_Id := Right_Opnd (N);
      T : Entity_Id;

      procedure Resolve_Set_Membership;
      --  Analysis has determined a unique type for the left operand. Use it to
      --  resolve the disjuncts.

      ----------------------------
      -- Resolve_Set_Membership --
      ----------------------------

      procedure Resolve_Set_Membership is
         Alt  : Node_Id;
         Ltyp : Entity_Id;

      begin
         --  If the left operand is overloaded, find type compatible with not
         --  overloaded alternative of the right operand.

         if Is_Overloaded (L) then
            Ltyp := Empty;
            Alt := First (Alternatives (N));
            while Present (Alt) loop
               if not Is_Overloaded (Alt) then
                  Ltyp := Intersect_Types (L, Alt);
                  exit;
               else
                  Next (Alt);
               end if;
            end loop;

            --  Unclear how to resolve expression if all alternatives are also
            --  overloaded.

            if No (Ltyp) then
               Error_Msg_N ("ambiguous expression", N);
            end if;

         else
            Ltyp := Etype (L);
         end if;

         Resolve (L, Ltyp);

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

            --  Alternative is an expression, a range
            --  or a subtype mark.

            if not Is_Entity_Name (Alt)
              or else not Is_Type (Entity (Alt))
            then
               Resolve (Alt, Ltyp);
            end if;

            Next (Alt);
         end loop;

         --  Check for duplicates for discrete case

         if Is_Discrete_Type (Ltyp) then
            declare
               type Ent is record
                  Alt : Node_Id;
                  Val : Uint;
               end record;

               Alts  : array (0 .. List_Length (Alternatives (N))) of Ent;
               Nalts : Nat;

            begin
               --  Loop checking duplicates. This is quadratic, but giant sets
               --  are unlikely in this context so it's a reasonable choice.

               Nalts := 0;
               Alt := First (Alternatives (N));
               while Present (Alt) loop
                  if Is_OK_Static_Expression (Alt)
                    and then (Nkind_In (Alt, N_Integer_Literal,
                                             N_Character_Literal)
                               or else Nkind (Alt) in N_Has_Entity)
                  then
                     Nalts := Nalts + 1;
                     Alts (Nalts) := (Alt, Expr_Value (Alt));

                     for J in 1 .. Nalts - 1 loop
                        if Alts (J).Val = Alts (Nalts).Val then
                           Error_Msg_Sloc := Sloc (Alts (J).Alt);
                           Error_Msg_N ("duplicate of value given#??", Alt);
                        end if;
                     end loop;
                  end if;

                  Alt := Next (Alt);
               end loop;
            end;
         end if;

         --  RM 4.5.2 (28.1/3) specifies that for types other than records or
         --  limited types, evaluation of a membership test uses the predefined
         --  equality for the type. This may be confusing to users, and the
         --  following warning appears useful for the most common case.

         if Is_Scalar_Type (Ltyp)
           and then Present (Get_User_Defined_Eq (Ltyp))
         then
            Error_Msg_NE
              ("membership test on& uses predefined equality?", N, Ltyp);
            Error_Msg_N
              ("\even if user-defined equality exists (RM 4.5.2 (28.1/3)?", N);
         end if;
      end Resolve_Set_Membership;

   --  Start of processing for Resolve_Membership_Op

   begin
      if L = Error or else R = Error then
         return;
      end if;

      if Present (Alternatives (N)) then
         Resolve_Set_Membership;
         goto SM_Exit;

      elsif not Is_Overloaded (R)
        and then
          (Etype (R) = Universal_Integer
             or else
           Etype (R) = Universal_Real)
        and then Is_Overloaded (L)
      then
         T := Etype (R);

      --  Ada 2005 (AI-251): Support the following case:

      --      type I is interface;
      --      type T is tagged ...

      --      function Test (O : I'Class) is
      --      begin
      --         return O in T'Class.
      --      end Test;

      --  In this case we have nothing else to do. The membership test will be
      --  done at run time.

      elsif Ada_Version >= Ada_2005
        and then Is_Class_Wide_Type (Etype (L))
        and then Is_Interface (Etype (L))
        and then not Is_Interface (Etype (R))
      then
         return;
      else
         T := Intersect_Types (L, R);
      end if;

      --  If mixed-mode operations are present and operands are all literal,
      --  the only interpretation involves Duration, which is probably not
      --  the intention of the programmer.

      if T = Any_Fixed then
         T := Unique_Fixed_Point_Type (N);

         if T = Any_Type then
            return;
         end if;
      end if;

      Resolve (L, T);
      Check_Unset_Reference (L);

      if Nkind (R) = N_Range
        and then not Is_Scalar_Type (T)
      then
         Error_Msg_N ("scalar type required for range", R);
      end if;

      if Is_Entity_Name (R) then
         Freeze_Expression (R);
      else
         Resolve (R, T);
         Check_Unset_Reference (R);
      end if;

      --  Here after resolving membership operation

      <<SM_Exit>>

      Eval_Membership_Op (N);
   end Resolve_Membership_Op;

   ------------------
   -- Resolve_Null --
   ------------------

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

   begin
      --  Handle restriction against anonymous null access values This
      --  restriction can be turned off using -gnatdj.

      --  Ada 2005 (AI-231): Remove restriction

      if Ada_Version < Ada_2005
        and then not Debug_Flag_J
        and then Ekind (Typ) = E_Anonymous_Access_Type
        and then Comes_From_Source (N)
      then
         --  In the common case of a call which uses an explicitly null value
         --  for an access parameter, give specialized error message.

         if Nkind (Parent (N)) in N_Subprogram_Call then
            Error_Msg_N
              ("null is not allowed as argument for an access parameter", N);

         --  Standard message for all other cases (are there any?)

         else
            Error_Msg_N
              ("null cannot be of an anonymous access type", N);
         end if;
      end if;

      --  Ada 2005 (AI-231): Generate the null-excluding check in case of
      --  assignment to a null-excluding object.

      if Ada_Version >= Ada_2005
        and then Can_Never_Be_Null (Typ)
        and then Nkind (Parent (N)) = N_Assignment_Statement
      then
         if Inside_Init_Proc then

            --  Decide whether to generate an if_statement around our
            --  null-excluding check to avoid them on certain internal object
            --  declarations by looking at the type the current Init_Proc
            --  belongs to.

            --  Generate:
            --    if T1b_skip_null_excluding_check then
            --       [constraint_error "access check failed"]
            --    end if;

            if Needs_Conditional_Null_Excluding_Check
                (Etype (First_Formal (Enclosing_Init_Proc)))
            then
               Insert_Action (N,
                 Make_If_Statement (Loc,
                   Condition       =>
                     Make_Identifier (Loc,
                       New_External_Name
                         (Chars (Typ), "_skip_null_excluding_check")),
                   Then_Statements =>
                     New_List (
                       Make_Raise_Constraint_Error (Loc,
                         Reason => CE_Access_Check_Failed))));

            --  Otherwise, simply create the check

            else
               Insert_Action (N,
                 Make_Raise_Constraint_Error (Loc,
                   Reason => CE_Access_Check_Failed));
            end if;
         else
            Insert_Action
              (Compile_Time_Constraint_Error (N,
                 "(Ada 2005) null not allowed in null-excluding objects??"),
               Make_Raise_Constraint_Error (Loc,
                 Reason => CE_Access_Check_Failed));
         end if;
      end if;

      --  In a distributed context, null for a remote access to subprogram may
      --  need to be replaced with a special record aggregate. In this case,
      --  return after having done the transformation.

      if (Ekind (Typ) = E_Record_Type
           or else Is_Remote_Access_To_Subprogram_Type (Typ))
        and then Remote_AST_Null_Value (N, Typ)
      then
         return;
      end if;

      --  The null literal takes its type from the context

      Set_Etype (N, Typ);
   end Resolve_Null;

   -----------------------
   -- Resolve_Op_Concat --
   -----------------------

   procedure Resolve_Op_Concat (N : Node_Id; Typ : Entity_Id) is

      --  We wish to avoid deep recursion, because concatenations are often
      --  deeply nested, as in A&B&...&Z. Therefore, we walk down the left
      --  operands nonrecursively until we find something that is not a simple
      --  concatenation (A in this case). We resolve that, and then walk back
      --  up the tree following Parent pointers, calling Resolve_Op_Concat_Rest
      --  to do the rest of the work at each level. The Parent pointers allow
      --  us to avoid recursion, and thus avoid running out of memory. See also
      --  Sem_Ch4.Analyze_Concatenation, where a similar approach is used.

      NN  : Node_Id := N;
      Op1 : Node_Id;

   begin
      --  The following code is equivalent to:

      --    Resolve_Op_Concat_First (NN, Typ);
      --    Resolve_Op_Concat_Arg (N, ...);
      --    Resolve_Op_Concat_Rest (N, Typ);

      --  where the Resolve_Op_Concat_Arg call recurses back here if the left
      --  operand is a concatenation.

      --  Walk down left operands

      loop
         Resolve_Op_Concat_First (NN, Typ);
         Op1 := Left_Opnd (NN);
         exit when not (Nkind (Op1) = N_Op_Concat
                         and then not Is_Array_Type (Component_Type (Typ))
                         and then Entity (Op1) = Entity (NN));
         NN := Op1;
      end loop;

      --  Now (given the above example) NN is A&B and Op1 is A

      --  First resolve Op1 ...

      Resolve_Op_Concat_Arg (NN, Op1, Typ, Is_Component_Left_Opnd  (NN));

      --  ... then walk NN back up until we reach N (where we started), calling
      --  Resolve_Op_Concat_Rest along the way.

      loop
         Resolve_Op_Concat_Rest (NN, Typ);
         exit when NN = N;
         NN := Parent (NN);
      end loop;

      if Base_Type (Etype (N)) /= Standard_String then
         Check_SPARK_05_Restriction
           ("result of concatenation should have type String", N);
      end if;
   end Resolve_Op_Concat;

   ---------------------------
   -- Resolve_Op_Concat_Arg --
   ---------------------------

   procedure Resolve_Op_Concat_Arg
     (N       : Node_Id;
      Arg     : Node_Id;
      Typ     : Entity_Id;
      Is_Comp : Boolean)
   is
      Btyp : constant Entity_Id := Base_Type (Typ);
      Ctyp : constant Entity_Id := Component_Type (Typ);

   begin
      if In_Instance then
         if Is_Comp
           or else (not Is_Overloaded (Arg)
                     and then Etype (Arg) /= Any_Composite
                     and then Covers (Ctyp, Etype (Arg)))
         then
            Resolve (Arg, Ctyp);
         else
            Resolve (Arg, Btyp);
         end if;

      --  If both Array & Array and Array & Component are visible, there is a
      --  potential ambiguity that must be reported.

      elsif Has_Compatible_Type (Arg, Ctyp) then
         if Nkind (Arg) = N_Aggregate
           and then Is_Composite_Type (Ctyp)
         then
            if Is_Private_Type (Ctyp) then
               Resolve (Arg, Btyp);

            --  If the operation is user-defined and not overloaded use its
            --  profile. The operation may be a renaming, in which case it has
            --  been rewritten, and we want the original profile.

            elsif not Is_Overloaded (N)
              and then Comes_From_Source (Entity (Original_Node (N)))
              and then Ekind (Entity (Original_Node (N))) = E_Function
            then
               Resolve (Arg,
                 Etype
                   (Next_Formal (First_Formal (Entity (Original_Node (N))))));
               return;

            --  Otherwise an aggregate may match both the array type and the
            --  component type.

            else
               Error_Msg_N ("ambiguous aggregate must be qualified", Arg);
               Set_Etype (Arg, Any_Type);
            end if;

         else
            if Is_Overloaded (Arg)
              and then Has_Compatible_Type (Arg, Typ)
              and then Etype (Arg) /= Any_Type
            then
               declare
                  I    : Interp_Index;
                  It   : Interp;
                  Func : Entity_Id;

               begin
                  Get_First_Interp (Arg, I, It);
                  Func := It.Nam;
                  Get_Next_Interp (I, It);

                  --  Special-case the error message when the overloading is
                  --  caused by a function that yields an array and can be
                  --  called without parameters.

                  if It.Nam = Func then
                     Error_Msg_Sloc := Sloc (Func);
                     Error_Msg_N ("ambiguous call to function#", Arg);
                     Error_Msg_NE
                       ("\\interpretation as call yields&", Arg, Typ);
                     Error_Msg_NE
                       ("\\interpretation as indexing of call yields&",
                         Arg, Component_Type (Typ));

                  else
                     Error_Msg_N ("ambiguous operand for concatenation!", Arg);

                     Get_First_Interp (Arg, I, It);
                     while Present (It.Nam) loop
                        Error_Msg_Sloc := Sloc (It.Nam);

                        if Base_Type (It.Typ) = Btyp
                             or else
                           Base_Type (It.Typ) = Base_Type (Ctyp)
                        then
                           Error_Msg_N -- CODEFIX
                             ("\\possible interpretation#", Arg);
                        end if;

                        Get_Next_Interp (I, It);
                     end loop;
                  end if;
               end;
            end if;

            Resolve (Arg, Component_Type (Typ));

            if Nkind (Arg) = N_String_Literal then
               Set_Etype (Arg, Component_Type (Typ));
            end if;

            if Arg = Left_Opnd (N) then
               Set_Is_Component_Left_Opnd (N);
            else
               Set_Is_Component_Right_Opnd (N);
            end if;
         end if;

      else
         Resolve (Arg, Btyp);
      end if;

      --  Concatenation is restricted in SPARK: each operand must be either a
      --  string literal, the name of a string constant, a static character or
      --  string expression, or another concatenation. Arg cannot be a
      --  concatenation here as callers of Resolve_Op_Concat_Arg call it
      --  separately on each final operand, past concatenation operations.

      if Is_Character_Type (Etype (Arg)) then
         if not Is_OK_Static_Expression (Arg) then
            Check_SPARK_05_Restriction
              ("character operand for concatenation should be static", Arg);
         end if;

      elsif Is_String_Type (Etype (Arg)) then
         if not (Nkind_In (Arg, N_Identifier, N_Expanded_Name)
                  and then Is_Constant_Object (Entity (Arg)))
           and then not Is_OK_Static_Expression (Arg)
         then
            Check_SPARK_05_Restriction
              ("string operand for concatenation should be static", Arg);
         end if;

      --  Do not issue error on an operand that is neither a character nor a
      --  string, as the error is issued in Resolve_Op_Concat.

      else
         null;
      end if;

      Check_Unset_Reference (Arg);
   end Resolve_Op_Concat_Arg;

   -----------------------------
   -- Resolve_Op_Concat_First --
   -----------------------------

   procedure Resolve_Op_Concat_First (N : Node_Id; Typ : Entity_Id) is
      Btyp : constant Entity_Id := Base_Type (Typ);
      Op1  : constant Node_Id := Left_Opnd (N);
      Op2  : constant Node_Id := Right_Opnd (N);

   begin
      --  The parser folds an enormous sequence of concatenations of string
      --  literals into "" & "...", where the Is_Folded_In_Parser flag is set
      --  in the right operand. If the expression resolves to a predefined "&"
      --  operator, all is well. Otherwise, the parser's folding is wrong, so
      --  we give an error. See P_Simple_Expression in Par.Ch4.

      if Nkind (Op2) = N_String_Literal
        and then Is_Folded_In_Parser (Op2)
        and then Ekind (Entity (N)) = E_Function
      then
         pragma Assert (Nkind (Op1) = N_String_Literal  --  should be ""
               and then String_Length (Strval (Op1)) = 0);
         Error_Msg_N ("too many user-defined concatenations", N);
         return;
      end if;

      Set_Etype (N, Btyp);

      if Is_Limited_Composite (Btyp) then
         Error_Msg_N ("concatenation not available for limited array", N);
         Explain_Limited_Type (Btyp, N);
      end if;
   end Resolve_Op_Concat_First;

   ----------------------------
   -- Resolve_Op_Concat_Rest --
   ----------------------------

   procedure Resolve_Op_Concat_Rest (N : Node_Id; Typ : Entity_Id) is
      Op1  : constant Node_Id := Left_Opnd (N);
      Op2  : constant Node_Id := Right_Opnd (N);

   begin
      Resolve_Op_Concat_Arg (N, Op2, Typ, Is_Component_Right_Opnd  (N));

      Generate_Operator_Reference (N, Typ);

      if Is_String_Type (Typ) then
         Eval_Concatenation (N);
      end if;

      --  If this is not a static concatenation, but the result is a string
      --  type (and not an array of strings) ensure that static string operands
      --  have their subtypes properly constructed.

      if Nkind (N) /= N_String_Literal
        and then Is_Character_Type (Component_Type (Typ))
      then
         Set_String_Literal_Subtype (Op1, Typ);
         Set_String_Literal_Subtype (Op2, Typ);
      end if;
   end Resolve_Op_Concat_Rest;

   ----------------------
   -- Resolve_Op_Expon --
   ----------------------

   procedure Resolve_Op_Expon (N : Node_Id; Typ : Entity_Id) is
      B_Typ : constant Entity_Id := Base_Type (Typ);

   begin
      --  Catch attempts to do fixed-point exponentiation with universal
      --  operands, which is a case where the illegality is not caught during
      --  normal operator analysis. This is not done in preanalysis mode
      --  since the tree is not fully decorated during preanalysis.

      if Full_Analysis then
         if Is_Fixed_Point_Type (Typ) and then Comes_From_Source (N) then
            Error_Msg_N ("exponentiation not available for fixed point", N);
            return;

         elsif Nkind (Parent (N)) in N_Op
           and then Present (Etype (Parent (N)))
           and then Is_Fixed_Point_Type (Etype (Parent (N)))
           and then Etype (N) = Universal_Real
           and then Comes_From_Source (N)
         then
            Error_Msg_N ("exponentiation not available for fixed point", N);
            return;
         end if;
      end if;

      if Comes_From_Source (N)
        and then Ekind (Entity (N)) = E_Function
        and then Is_Imported (Entity (N))
        and then Is_Intrinsic_Subprogram (Entity (N))
      then
         Resolve_Intrinsic_Operator (N, Typ);
         return;
      end if;

      if Etype (Left_Opnd (N)) = Universal_Integer
        or else Etype (Left_Opnd (N)) = Universal_Real
      then
         Check_For_Visible_Operator (N, B_Typ);
      end if;

      --  We do the resolution using the base type, because intermediate values
      --  in expressions are always of the base type, not a subtype of it.

      Resolve (Left_Opnd (N), B_Typ);
      Resolve (Right_Opnd (N), Standard_Integer);

      --  For integer types, right argument must be in Natural range

      if Is_Integer_Type (Typ) then
         Apply_Scalar_Range_Check (Right_Opnd (N), Standard_Natural);
      end if;

      Check_Unset_Reference (Left_Opnd  (N));
      Check_Unset_Reference (Right_Opnd (N));

      Set_Etype (N, B_Typ);
      Generate_Operator_Reference (N, B_Typ);

      Analyze_Dimension (N);

      if Ada_Version >= Ada_2012 and then Has_Dimension_System (B_Typ) then
         --  Evaluate the exponentiation operator for dimensioned type

         Eval_Op_Expon_For_Dimensioned_Type (N, B_Typ);
      else
         Eval_Op_Expon (N);
      end if;

      --  Set overflow checking bit. Much cleverer code needed here eventually
      --  and perhaps the Resolve routines should be separated for the various
      --  arithmetic operations, since they will need different processing. ???

      if Nkind (N) in N_Op then
         if not Overflow_Checks_Suppressed (Etype (N)) then
            Enable_Overflow_Check (N);
         end if;
      end if;
   end Resolve_Op_Expon;

   --------------------
   -- Resolve_Op_Not --
   --------------------

   procedure Resolve_Op_Not (N : Node_Id; Typ : Entity_Id) is
      B_Typ : Entity_Id;

      function Parent_Is_Boolean return Boolean;
      --  This function determines if the parent node is a boolean operator or
      --  operation (comparison op, membership test, or short circuit form) and
      --  the not in question is the left operand of this operation. Note that
      --  if the not is in parens, then false is returned.

      -----------------------
      -- Parent_Is_Boolean --
      -----------------------

      function Parent_Is_Boolean return Boolean is
      begin
         if Paren_Count (N) /= 0 then
            return False;

         else
            case Nkind (Parent (N)) is
               when N_And_Then
                  | N_In
                  | N_Not_In
                  | N_Op_And
                  | N_Op_Eq
                  | N_Op_Ge
                  | N_Op_Gt
                  | N_Op_Le
                  | N_Op_Lt
                  | N_Op_Ne
                  | N_Op_Or
                  | N_Op_Xor
                  | N_Or_Else
               =>
                  return Left_Opnd (Parent (N)) = N;

               when others =>
                  return False;
            end case;
         end if;
      end Parent_Is_Boolean;

   --  Start of processing for Resolve_Op_Not

   begin
      --  Predefined operations on scalar types yield the base type. On the
      --  other hand, logical operations on arrays yield the type of the
      --  arguments (and the context).

      if Is_Array_Type (Typ) then
         B_Typ := Typ;
      else
         B_Typ := Base_Type (Typ);
      end if;

      --  Straightforward case of incorrect arguments

      if not Valid_Boolean_Arg (Typ) then
         Error_Msg_N ("invalid operand type for operator&", N);
         Set_Etype (N, Any_Type);
         return;

      --  Special case of probable missing parens

      elsif Typ = Universal_Integer or else Typ = Any_Modular then
         if Parent_Is_Boolean then
            Error_Msg_N
              ("operand of not must be enclosed in parentheses",
               Right_Opnd (N));
         else
            Error_Msg_N
              ("no modular type available in this context", N);
         end if;

         Set_Etype (N, Any_Type);
         return;

      --  OK resolution of NOT

      else
         --  Warn if non-boolean types involved. This is a case like not a < b
         --  where a and b are modular, where we will get (not a) < b and most
         --  likely not (a < b) was intended.

         if Warn_On_Questionable_Missing_Parens
           and then not Is_Boolean_Type (Typ)
           and then Parent_Is_Boolean
         then
            Error_Msg_N ("?q?not expression should be parenthesized here!", N);
         end if;

         --  Warn on double negation if checking redundant constructs

         if Warn_On_Redundant_Constructs
           and then Comes_From_Source (N)
           and then Comes_From_Source (Right_Opnd (N))
           and then Root_Type (Typ) = Standard_Boolean
           and then Nkind (Right_Opnd (N)) = N_Op_Not
         then
            Error_Msg_N ("redundant double negation?r?", N);
         end if;

         --  Complete resolution and evaluation of NOT
         --  If argument is an equality and expected type is boolean, that
         --  expected type has no effect on resolution, and there are
         --  special rules for resolution of Eq, Neq in the presence of
         --  overloaded operands, so we directly call its resolution routines.

         declare
            Opnd : constant Node_Id := Right_Opnd (N);
            Op_Id : Entity_Id;

         begin
            if B_Typ = Standard_Boolean
              and then Nkind_In (Opnd, N_Op_Eq, N_Op_Ne)
              and then Is_Overloaded (Opnd)
            then
               Resolve_Equality_Op (Opnd, B_Typ);
               Op_Id := Entity (Opnd);

               if Ekind (Op_Id) = E_Function
                 and then not Is_Intrinsic_Subprogram (Op_Id)
               then
                  Rewrite_Operator_As_Call (Opnd, Op_Id);
               end if;

               if not Inside_A_Generic or else Is_Entity_Name (Opnd) then
                  Freeze_Expression (Opnd);
               end if;

               Expand (Opnd);

            else
               Resolve (Opnd, B_Typ);
            end if;

            Check_Unset_Reference (Opnd);
         end;

         Set_Etype (N, B_Typ);
         Generate_Operator_Reference (N, B_Typ);
         Eval_Op_Not (N);
      end if;
   end Resolve_Op_Not;

   -----------------------------
   -- Resolve_Operator_Symbol --
   -----------------------------

   --  Nothing to be done, all resolved already

   procedure Resolve_Operator_Symbol (N : Node_Id; Typ : Entity_Id) is
      pragma Warnings (Off, N);
      pragma Warnings (Off, Typ);

   begin
      null;
   end Resolve_Operator_Symbol;

   ----------------------------------
   -- Resolve_Qualified_Expression --
   ----------------------------------

   procedure Resolve_Qualified_Expression (N : Node_Id; Typ : Entity_Id) is
      pragma Warnings (Off, Typ);

      Target_Typ : constant Entity_Id := Entity (Subtype_Mark (N));
      Expr       : constant Node_Id   := Expression (N);

   begin
      Resolve (Expr, Target_Typ);

      --  Protect call to Matching_Static_Array_Bounds to avoid costly
      --  operation if not needed.

      if Restriction_Check_Required (SPARK_05)
        and then Is_Array_Type (Target_Typ)
        and then Is_Array_Type (Etype (Expr))
        and then Etype (Expr) /= Any_Composite  --  or else Expr in error
        and then not Matching_Static_Array_Bounds (Target_Typ, Etype (Expr))
      then
         Check_SPARK_05_Restriction
           ("array types should have matching static bounds", N);
      end if;

      --  A qualified expression requires an exact match of the type, class-
      --  wide matching is not allowed. However, if the qualifying type is
      --  specific and the expression has a class-wide type, it may still be
      --  okay, since it can be the result of the expansion of a call to a
      --  dispatching function, so we also have to check class-wideness of the
      --  type of the expression's original node.

      if (Is_Class_Wide_Type (Target_Typ)
           or else
             (Is_Class_Wide_Type (Etype (Expr))
               and then Is_Class_Wide_Type (Etype (Original_Node (Expr)))))
        and then Base_Type (Etype (Expr)) /= Base_Type (Target_Typ)
      then
         Wrong_Type (Expr, Target_Typ);
      end if;

      --  If the target type is unconstrained, then we reset the type of the
      --  result from the type of the expression. For other cases, the actual
      --  subtype of the expression is the target type.

      if Is_Composite_Type (Target_Typ)
        and then not Is_Constrained (Target_Typ)
      then
         Set_Etype (N, Etype (Expr));
      end if;

      Analyze_Dimension (N);
      Eval_Qualified_Expression (N);

      --  If we still have a qualified expression after the static evaluation,
      --  then apply a scalar range check if needed. The reason that we do this
      --  after the Eval call is that otherwise, the application of the range
      --  check may convert an illegal static expression and result in warning
      --  rather than giving an error (e.g Integer'(Integer'Last + 1)).

      if Nkind (N) = N_Qualified_Expression and then Is_Scalar_Type (Typ) then
         Apply_Scalar_Range_Check (Expr, Typ);
      end if;

      --  Finally, check whether a predicate applies to the target type. This
      --  comes from AI12-0100. As for type conversions, check the enclosing
      --  context to prevent an infinite expansion.

      if Has_Predicates (Target_Typ) then
         if Nkind (Parent (N)) = N_Function_Call
           and then Present (Name (Parent (N)))
           and then (Is_Predicate_Function (Entity (Name (Parent (N))))
                       or else
                     Is_Predicate_Function_M (Entity (Name (Parent (N)))))
         then
            null;

         --  In the case of a qualified expression in an allocator, the check
         --  is applied when expanding the allocator, so avoid redundant check.

         elsif Nkind (N) = N_Qualified_Expression
           and then Nkind (Parent (N)) /= N_Allocator
         then
            Apply_Predicate_Check (N, Target_Typ);
         end if;
      end if;
   end Resolve_Qualified_Expression;

   ------------------------------
   -- Resolve_Raise_Expression --
   ------------------------------

   procedure Resolve_Raise_Expression (N : Node_Id; Typ : Entity_Id) is
   begin
      if Typ = Raise_Type then
         Error_Msg_N ("cannot find unique type for raise expression", N);
         Set_Etype (N, Any_Type);
      else
         Set_Etype (N, Typ);
      end if;
   end Resolve_Raise_Expression;

   -------------------
   -- Resolve_Range --
   -------------------

   procedure Resolve_Range (N : Node_Id; Typ : Entity_Id) is
      L : constant Node_Id := Low_Bound (N);
      H : constant Node_Id := High_Bound (N);

      function First_Last_Ref return Boolean;
      --  Returns True if N is of the form X'First .. X'Last where X is the
      --  same entity for both attributes.

      --------------------
      -- First_Last_Ref --
      --------------------

      function First_Last_Ref return Boolean is
         Lorig : constant Node_Id := Original_Node (L);
         Horig : constant Node_Id := Original_Node (H);

      begin
         if Nkind (Lorig) = N_Attribute_Reference
           and then Nkind (Horig) = N_Attribute_Reference
           and then Attribute_Name (Lorig) = Name_First
           and then Attribute_Name (Horig) = Name_Last
         then
            declare
               PL : constant Node_Id := Prefix (Lorig);
               PH : constant Node_Id := Prefix (Horig);
            begin
               if Is_Entity_Name (PL)
                 and then Is_Entity_Name (PH)
                 and then Entity (PL) = Entity (PH)
               then
                  return True;
               end if;
            end;
         end if;

         return False;
      end First_Last_Ref;

   --  Start of processing for Resolve_Range

   begin
      Set_Etype (N, Typ);

      --  The lower bound should be in Typ. The higher bound can be in Typ's
      --  base type if the range is null. It may still be invalid if it is
      --  higher than the lower bound. This is checked later in the context in
      --  which the range appears.

      Resolve (L, Typ);
      Resolve (H, Base_Type (Typ));

      --  Reanalyze the lower bound after both bounds have been analyzed, so
      --  that the range is known to be static or not by now. This may trigger
      --  more compile-time evaluation, which is useful for static analysis
      --  with GNATprove. This is not needed for compilation or static analysis
      --  with CodePeer, as full expansion does that evaluation then.

      if GNATprove_Mode then
         Set_Analyzed (L, False);
         Resolve (L, Typ);
      end if;

      --  Check for inappropriate range on unordered enumeration type

      if Bad_Unordered_Enumeration_Reference (N, Typ)

        --  Exclude X'First .. X'Last if X is the same entity for both

        and then not First_Last_Ref
      then
         Error_Msg_Sloc := Sloc (Typ);
         Error_Msg_NE
           ("subrange of unordered enumeration type& declared#?U?", N, Typ);
      end if;

      Check_Unset_Reference (L);
      Check_Unset_Reference (H);

      --  We have to check the bounds for being within the base range as
      --  required for a non-static context. Normally this is automatic and
      --  done as part of evaluating expressions, but the N_Range node is an
      --  exception, since in GNAT we consider this node to be a subexpression,
      --  even though in Ada it is not. The circuit in Sem_Eval could check for
      --  this, but that would put the test on the main evaluation path for
      --  expressions.

      Check_Non_Static_Context (L);
      Check_Non_Static_Context (H);

      --  Check for an ambiguous range over character literals. This will
      --  happen with a membership test involving only literals.

      if Typ = Any_Character then
         Ambiguous_Character (L);
         Set_Etype (N, Any_Type);
         return;
      end if;

      --  If bounds are static, constant-fold them, so size computations are
      --  identical between front-end and back-end. Do not perform this
      --  transformation while analyzing generic units, as type information
      --  would be lost when reanalyzing the constant node in the instance.

      if Is_Discrete_Type (Typ) and then Expander_Active then
         if Is_OK_Static_Expression (L) then
            Fold_Uint (L, Expr_Value (L), Is_OK_Static_Expression (L));
         end if;

         if Is_OK_Static_Expression (H) then
            Fold_Uint (H, Expr_Value (H), Is_OK_Static_Expression (H));
         end if;
      end if;
   end Resolve_Range;

   --------------------------
   -- Resolve_Real_Literal --
   --------------------------

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

   begin
      --  Special processing for fixed-point literals to make sure that the
      --  value is an exact multiple of small where this is required. We skip
      --  this for the universal real case, and also for generic types.

      if Is_Fixed_Point_Type (Typ)
        and then Typ /= Universal_Fixed
        and then Typ /= Any_Fixed
        and then not Is_Generic_Type (Typ)
      then
         declare
            Val   : constant Ureal := Realval (N);
            Cintr : constant Ureal := Val / Small_Value (Typ);
            Cint  : constant Uint  := UR_Trunc (Cintr);
            Den   : constant Uint  := Norm_Den (Cintr);
            Stat  : Boolean;

         begin
            --  Case of literal is not an exact multiple of the Small

            if Den /= 1 then

               --  For a source program literal for a decimal fixed-point type,
               --  this is statically illegal (RM 4.9(36)).

               if Is_Decimal_Fixed_Point_Type (Typ)
                 and then Actual_Typ = Universal_Real
                 and then Comes_From_Source (N)
               then
                  Error_Msg_N ("value has extraneous low order digits", N);
               end if;

               --  Generate a warning if literal from source

               if Is_OK_Static_Expression (N)
                 and then Warn_On_Bad_Fixed_Value
               then
                  Error_Msg_N
                    ("?b?static fixed-point value is not a multiple of Small!",
                     N);
               end if;

               --  Replace literal by a value that is the exact representation
               --  of a value of the type, i.e. a multiple of the small value,
               --  by truncation, since Machine_Rounds is false for all GNAT
               --  fixed-point types (RM 4.9(38)).

               Stat := Is_OK_Static_Expression (N);
               Rewrite (N,
                 Make_Real_Literal (Sloc (N),
                   Realval => Small_Value (Typ) * Cint));

               Set_Is_Static_Expression (N, Stat);
            end if;

            --  In all cases, set the corresponding integer field

            Set_Corresponding_Integer_Value (N, Cint);
         end;
      end if;

      --  Now replace the actual type by the expected type as usual

      Set_Etype (N, Typ);
      Eval_Real_Literal (N);
   end Resolve_Real_Literal;

   -----------------------
   -- Resolve_Reference --
   -----------------------

   procedure Resolve_Reference (N : Node_Id; Typ : Entity_Id) is
      P : constant Node_Id := Prefix (N);

   begin
      --  Replace general access with specific type

      if Ekind (Etype (N)) = E_Allocator_Type then
         Set_Etype (N, Base_Type (Typ));
      end if;

      Resolve (P, Designated_Type (Etype (N)));

      --  If we are taking the reference of a volatile entity, then treat it as
      --  a potential modification of this entity. This is too conservative,
      --  but necessary because remove side effects can cause transformations
      --  of normal assignments into reference sequences that otherwise fail to
      --  notice the modification.

      if Is_Entity_Name (P) and then Treat_As_Volatile (Entity (P)) then
         Note_Possible_Modification (P, Sure => False);
      end if;
   end Resolve_Reference;

   --------------------------------
   -- Resolve_Selected_Component --
   --------------------------------

   procedure Resolve_Selected_Component (N : Node_Id; Typ : Entity_Id) is
      Comp  : Entity_Id;
      Comp1 : Entity_Id        := Empty; -- prevent junk warning
      P     : constant Node_Id := Prefix (N);
      S     : constant Node_Id := Selector_Name (N);
      T     : Entity_Id        := Etype (P);
      I     : Interp_Index;
      I1    : Interp_Index := 0; -- prevent junk warning
      It    : Interp;
      It1   : Interp;
      Found : Boolean;

      function Init_Component return Boolean;
      --  Check whether this is the initialization of a component within an
      --  init proc (by assignment or call to another init proc). If true,
      --  there is no need for a discriminant check.

      --------------------
      -- Init_Component --
      --------------------

      function Init_Component return Boolean is
      begin
         return Inside_Init_Proc
           and then Nkind (Prefix (N)) = N_Identifier
           and then Chars (Prefix (N)) = Name_uInit
           and then Nkind (Parent (Parent (N))) = N_Case_Statement_Alternative;
      end Init_Component;

   --  Start of processing for Resolve_Selected_Component

   begin
      if Is_Overloaded (P) then

         --  Use the context type to select the prefix that has a selector
         --  of the correct name and type.

         Found := False;
         Get_First_Interp (P, I, It);

         Search : while Present (It.Typ) loop
            if Is_Access_Type (It.Typ) then
               T := Designated_Type (It.Typ);
            else
               T := It.Typ;
            end if;

            --  Locate selected component. For a private prefix the selector
            --  can denote a discriminant.

            if Is_Record_Type (T) or else Is_Private_Type (T) then

               --  The visible components of a class-wide type are those of
               --  the root type.

               if Is_Class_Wide_Type (T) then
                  T := Etype (T);
               end if;

               Comp := First_Entity (T);
               while Present (Comp) loop
                  if Chars (Comp) = Chars (S)
                    and then Covers (Typ, Etype (Comp))
                  then
                     if not Found then
                        Found := True;
                        I1  := I;
                        It1 := It;
                        Comp1 := Comp;

                     else
                        It := Disambiguate (P, I1, I, Any_Type);

                        if It = No_Interp then
                           Error_Msg_N
                             ("ambiguous prefix for selected component",  N);
                           Set_Etype (N, Typ);
                           return;

                        else
                           It1 := It;

                           --  There may be an implicit dereference. Retrieve
                           --  designated record type.

                           if Is_Access_Type (It1.Typ) then
                              T := Designated_Type (It1.Typ);
                           else
                              T := It1.Typ;
                           end if;

                           if Scope (Comp1) /= T then

                              --  Resolution chooses the new interpretation.
                              --  Find the component with the right name.

                              Comp1 := First_Entity (T);
                              while Present (Comp1)
                                and then Chars (Comp1) /= Chars (S)
                              loop
                                 Comp1 := Next_Entity (Comp1);
                              end loop;
                           end if;

                           exit Search;
                        end if;
                     end if;
                  end if;

                  Comp := Next_Entity (Comp);
               end loop;
            end if;

            Get_Next_Interp (I, It);
         end loop Search;

         --  There must be a legal interpretation at this point

         pragma Assert (Found);
         Resolve (P, It1.Typ);

         --  In general the expected type is the type of the context, not the
         --  type of the candidate selected component.

         Set_Etype (N, Typ);
         Set_Entity_With_Checks (S, Comp1);

         --  The type of the context and that of the component are
         --  compatible and in general identical, but if they are anonymous
         --  access-to-subprogram types, the relevant type is that of the
         --  component. This matters in Unnest_Subprograms mode, where the
         --  relevant context is the one in which the type is declared, not
         --  the point of use. This determines what activation record to use.

         if Ekind (Typ) = E_Anonymous_Access_Subprogram_Type then
            Set_Etype (N, Etype (Comp1));

         --  When the type of the component is an access to a class-wide type
         --  the relevant type is that of the component (since in such case we
         --  may need to generate implicit type conversions or dispatching
         --  calls).

         elsif Is_Access_Type (Typ)
           and then not Is_Class_Wide_Type (Designated_Type (Typ))
           and then Is_Class_Wide_Type (Designated_Type (Etype (Comp1)))
         then
            Set_Etype (N, Etype (Comp1));
         end if;

      else
         --  Resolve prefix with its type

         Resolve (P, T);
      end if;

      --  Generate cross-reference. We needed to wait until full overloading
      --  resolution was complete to do this, since otherwise we can't tell if
      --  we are an lvalue or not.

      if May_Be_Lvalue (N) then
         Generate_Reference (Entity (S), S, 'm');
      else
         Generate_Reference (Entity (S), S, 'r');
      end if;

      --  If prefix is an access type, the node will be transformed into an
      --  explicit dereference during expansion. The type of the node is the
      --  designated type of that of the prefix.

      if Is_Access_Type (Etype (P)) then
         T := Designated_Type (Etype (P));
         Check_Fully_Declared_Prefix (T, P);

      else
         T := Etype (P);

         --  If the prefix is an entity it may have a deferred reference set
         --  during analysis of the selected component. After resolution we
         --  can transform it into a proper reference. This prevents spurious
         --  warnings on useless assignments when the same selected component
         --  is the actual for an out parameter in a subsequent call.

         if Is_Entity_Name (P)
           and then Has_Deferred_Reference (Entity (P))
         then
            if May_Be_Lvalue (N) then
               Generate_Reference (Entity (P), P, 'm');
            else
               Generate_Reference (Entity (P), P, 'r');
            end if;
         end if;
      end if;

      --  Set flag for expander if discriminant check required on a component
      --  appearing within a variant.

      if Has_Discriminants (T)
        and then Ekind (Entity (S)) = E_Component
        and then Present (Original_Record_Component (Entity (S)))
        and then Ekind (Original_Record_Component (Entity (S))) = E_Component
        and then
          Is_Declared_Within_Variant (Original_Record_Component (Entity (S)))
        and then not Discriminant_Checks_Suppressed (T)
        and then not Init_Component
      then
         Set_Do_Discriminant_Check (N);
      end if;

      if Ekind (Entity (S)) = E_Void then
         Error_Msg_N ("premature use of component", S);
      end if;

      --  If the prefix is a record conversion, this may be a renamed
      --  discriminant whose bounds differ from those of the original
      --  one, so we must ensure that a range check is performed.

      if Nkind (P) = N_Type_Conversion
        and then Ekind (Entity (S)) = E_Discriminant
        and then Is_Discrete_Type (Typ)
      then
         Set_Etype (N, Base_Type (Typ));
      end if;

      --  Note: No Eval processing is required, because the prefix is of a
      --  record type, or protected type, and neither can possibly be static.

      --  If the record type is atomic, and the component is non-atomic, then
      --  this is worth a warning, since we have a situation where the access
      --  to the component may cause extra read/writes of the atomic array
      --  object, or partial word accesses, both of which may be unexpected.

      if Nkind (N) = N_Selected_Component
        and then Is_Atomic_Ref_With_Address (N)
        and then not Is_Atomic (Entity (S))
        and then not Is_Atomic (Etype (Entity (S)))
      then
         Error_Msg_N
           ("??access to non-atomic component of atomic record",
            Prefix (N));
         Error_Msg_N
           ("\??may cause unexpected accesses to atomic object",
            Prefix (N));
      end if;

      Analyze_Dimension (N);
   end Resolve_Selected_Component;

   -------------------
   -- Resolve_Shift --
   -------------------

   procedure Resolve_Shift (N : Node_Id; Typ : Entity_Id) is
      B_Typ : constant Entity_Id := Base_Type (Typ);
      L     : constant Node_Id   := Left_Opnd  (N);
      R     : constant Node_Id   := Right_Opnd (N);

   begin
      --  We do the resolution using the base type, because intermediate values
      --  in expressions always are of the base type, not a subtype of it.

      Resolve (L, B_Typ);
      Resolve (R, Standard_Natural);

      Check_Unset_Reference (L);
      Check_Unset_Reference (R);

      Set_Etype (N, B_Typ);
      Generate_Operator_Reference (N, B_Typ);
      Eval_Shift (N);
   end Resolve_Shift;

   ---------------------------
   -- Resolve_Short_Circuit --
   ---------------------------

   procedure Resolve_Short_Circuit (N : Node_Id; Typ : Entity_Id) is
      B_Typ : constant Entity_Id := Base_Type (Typ);
      L     : constant Node_Id   := Left_Opnd  (N);
      R     : constant Node_Id   := Right_Opnd (N);

   begin
      --  Ensure all actions associated with the left operand (e.g.
      --  finalization of transient objects) are fully evaluated locally within
      --  an expression with actions. This is particularly helpful for coverage
      --  analysis. However this should not happen in generics or if option
      --  Minimize_Expression_With_Actions is set.

      if Expander_Active and not Minimize_Expression_With_Actions then
         declare
            Reloc_L : constant Node_Id := Relocate_Node (L);
         begin
            Save_Interps (Old_N => L, New_N => Reloc_L);

            Rewrite (L,
              Make_Expression_With_Actions (Sloc (L),
                Actions    => New_List,
                Expression => Reloc_L));

            --  Set Comes_From_Source on L to preserve warnings for unset
            --  reference.

            Set_Comes_From_Source (L, Comes_From_Source (Reloc_L));
         end;
      end if;

      Resolve (L, B_Typ);
      Resolve (R, B_Typ);

      --  Check for issuing warning for always False assert/check, this happens
      --  when assertions are turned off, in which case the pragma Assert/Check
      --  was transformed into:

      --     if False and then <condition> then ...

      --  and we detect this pattern

      if Warn_On_Assertion_Failure
        and then Is_Entity_Name (R)
        and then Entity (R) = Standard_False
        and then Nkind (Parent (N)) = N_If_Statement
        and then Nkind (N) = N_And_Then
        and then Is_Entity_Name (L)
        and then Entity (L) = Standard_False
      then
         declare
            Orig : constant Node_Id := Original_Node (Parent (N));

         begin
            --  Special handling of Asssert pragma

            if Nkind (Orig) = N_Pragma
              and then Pragma_Name (Orig) = Name_Assert
            then
               declare
                  Expr : constant Node_Id :=
                           Original_Node
                             (Expression
                               (First (Pragma_Argument_Associations (Orig))));

               begin
                  --  Don't warn if original condition is explicit False,
                  --  since obviously the failure is expected in this case.

                  if Is_Entity_Name (Expr)
                    and then Entity (Expr) = Standard_False
                  then
                     null;

                  --  Issue warning. We do not want the deletion of the
                  --  IF/AND-THEN to take this message with it. We achieve this
                  --  by making sure that the expanded code points to the Sloc
                  --  of the expression, not the original pragma.

                  else
                     --  Note: Use Error_Msg_F here rather than Error_Msg_N.
                     --  The source location of the expression is not usually
                     --  the best choice here. For example, it gets located on
                     --  the last AND keyword in a chain of boolean expressiond
                     --  AND'ed together. It is best to put the message on the
                     --  first character of the assertion, which is the effect
                     --  of the First_Node call here.

                     Error_Msg_F
                       ("?A?assertion would fail at run time!",
                        Expression
                          (First (Pragma_Argument_Associations (Orig))));
                  end if;
               end;

            --  Similar processing for Check pragma

            elsif Nkind (Orig) = N_Pragma
              and then Pragma_Name (Orig) = Name_Check
            then
               --  Don't want to warn if original condition is explicit False

               declare
                  Expr : constant Node_Id :=
                    Original_Node
                      (Expression
                        (Next (First (Pragma_Argument_Associations (Orig)))));
               begin
                  if Is_Entity_Name (Expr)
                    and then Entity (Expr) = Standard_False
                  then
                     null;

                  --  Post warning

                  else
                     --  Again use Error_Msg_F rather than Error_Msg_N, see
                     --  comment above for an explanation of why we do this.

                     Error_Msg_F
                       ("?A?check would fail at run time!",
                        Expression
                          (Last (Pragma_Argument_Associations (Orig))));
                  end if;
               end;
            end if;
         end;
      end if;

      --  Continue with processing of short circuit

      Check_Unset_Reference (L);
      Check_Unset_Reference (R);

      Set_Etype (N, B_Typ);
      Eval_Short_Circuit (N);
   end Resolve_Short_Circuit;

   -------------------
   -- Resolve_Slice --
   -------------------

   procedure Resolve_Slice (N : Node_Id; Typ : Entity_Id) is
      Drange     : constant Node_Id := Discrete_Range (N);
      Name       : constant Node_Id := Prefix (N);
      Array_Type : Entity_Id        := Empty;
      Dexpr      : Node_Id          := Empty;
      Index_Type : Entity_Id;

   begin
      if Is_Overloaded (Name) then

         --  Use the context type to select the prefix that yields the correct
         --  array type.

         declare
            I      : Interp_Index;
            I1     : Interp_Index := 0;
            It     : Interp;
            P      : constant Node_Id := Prefix (N);
            Found  : Boolean := False;

         begin
            Get_First_Interp (P, I,  It);
            while Present (It.Typ) loop
               if (Is_Array_Type (It.Typ)
                    and then Covers (Typ,  It.Typ))
                 or else (Is_Access_Type (It.Typ)
                           and then Is_Array_Type (Designated_Type (It.Typ))
                           and then Covers (Typ, Designated_Type (It.Typ)))
               then
                  if Found then
                     It := Disambiguate (P, I1, I, Any_Type);

                     if It = No_Interp then
                        Error_Msg_N ("ambiguous prefix for slicing",  N);
                        Set_Etype (N, Typ);
                        return;
                     else
                        Found := True;
                        Array_Type := It.Typ;
                        I1 := I;
                     end if;
                  else
                     Found := True;
                     Array_Type := It.Typ;
                     I1 := I;
                  end if;
               end if;

               Get_Next_Interp (I, It);
            end loop;
         end;

      else
         Array_Type := Etype (Name);
      end if;

      Resolve (Name, Array_Type);

      if Is_Access_Type (Array_Type) then
         Apply_Access_Check (N);
         Array_Type := Designated_Type (Array_Type);

         --  If the prefix is an access to an unconstrained array, we must use
         --  the actual subtype of the object to perform the index checks. The
         --  object denoted by the prefix is implicit in the node, so we build
         --  an explicit representation for it in order to compute the actual
         --  subtype.

         if not Is_Constrained (Array_Type) then
            Remove_Side_Effects (Prefix (N));

            declare
               Obj : constant Node_Id :=
                       Make_Explicit_Dereference (Sloc (N),
                         Prefix => New_Copy_Tree (Prefix (N)));
            begin
               Set_Etype (Obj, Array_Type);
               Set_Parent (Obj, Parent (N));
               Array_Type := Get_Actual_Subtype (Obj);
            end;
         end if;

      elsif Is_Entity_Name (Name)
        or else Nkind (Name) = N_Explicit_Dereference
        or else (Nkind (Name) = N_Function_Call
                  and then not Is_Constrained (Etype (Name)))
      then
         Array_Type := Get_Actual_Subtype (Name);

      --  If the name is a selected component that depends on discriminants,
      --  build an actual subtype for it. This can happen only when the name
      --  itself is overloaded; otherwise the actual subtype is created when
      --  the selected component is analyzed.

      elsif Nkind (Name) = N_Selected_Component
        and then Full_Analysis
        and then Depends_On_Discriminant (First_Index (Array_Type))
      then
         declare
            Act_Decl : constant Node_Id :=
                         Build_Actual_Subtype_Of_Component (Array_Type, Name);
         begin
            Insert_Action (N, Act_Decl);
            Array_Type := Defining_Identifier (Act_Decl);
         end;

      --  Maybe this should just be "else", instead of checking for the
      --  specific case of slice??? This is needed for the case where the
      --  prefix is an Image attribute, which gets expanded to a slice, and so
      --  has a constrained subtype which we want to use for the slice range
      --  check applied below (the range check won't get done if the
      --  unconstrained subtype of the 'Image is used).

      elsif Nkind (Name) = N_Slice then
         Array_Type := Etype (Name);
      end if;

      --  Obtain the type of the array index

      if Ekind (Array_Type) = E_String_Literal_Subtype then
         Index_Type := Etype (String_Literal_Low_Bound (Array_Type));
      else
         Index_Type := Etype (First_Index (Array_Type));
      end if;

      --  If name was overloaded, set slice type correctly now

      Set_Etype (N, Array_Type);

      --  Handle the generation of a range check that compares the array index
      --  against the discrete_range. The check is not applied to internally
      --  built nodes associated with the expansion of dispatch tables. Check
      --  that Ada.Tags has already been loaded to avoid extra dependencies on
      --  the unit.

      if Tagged_Type_Expansion
        and then RTU_Loaded (Ada_Tags)
        and then Nkind (Prefix (N)) = N_Selected_Component
        and then Present (Entity (Selector_Name (Prefix (N))))
        and then Entity (Selector_Name (Prefix (N))) =
                   RTE_Record_Component (RE_Prims_Ptr)
      then
         null;

      --  The discrete_range is specified by a subtype indication. Create a
      --  shallow copy and inherit the type, parent and source location from
      --  the discrete_range. This ensures that the range check is inserted
      --  relative to the slice and that the runtime exception points to the
      --  proper construct.

      elsif Is_Entity_Name (Drange) then
         Dexpr := New_Copy (Scalar_Range (Entity (Drange)));

         Set_Etype  (Dexpr, Etype  (Drange));
         Set_Parent (Dexpr, Parent (Drange));
         Set_Sloc   (Dexpr, Sloc   (Drange));

      --  The discrete_range is a regular range. Resolve the bounds and remove
      --  their side effects.

      else
         Resolve (Drange, Base_Type (Index_Type));

         if Nkind (Drange) = N_Range then
            Force_Evaluation (Low_Bound  (Drange));
            Force_Evaluation (High_Bound (Drange));

            Dexpr := Drange;
         end if;
      end if;

      if Present (Dexpr) then
         Apply_Range_Check (Dexpr, Index_Type);
      end if;

      Set_Slice_Subtype (N);

      --  Check bad use of type with predicates

      declare
         Subt : Entity_Id;

      begin
         if Nkind (Drange) = N_Subtype_Indication
           and then Has_Predicates (Entity (Subtype_Mark (Drange)))
         then
            Subt := Entity (Subtype_Mark (Drange));
         else
            Subt := Etype (Drange);
         end if;

         if Has_Predicates (Subt) then
            Bad_Predicated_Subtype_Use
              ("subtype& has predicate, not allowed in slice", Drange, Subt);
         end if;
      end;

      --  Otherwise here is where we check suspicious indexes

      if Nkind (Drange) = N_Range then
         Warn_On_Suspicious_Index (Name, Low_Bound  (Drange));
         Warn_On_Suspicious_Index (Name, High_Bound (Drange));
      end if;

      Analyze_Dimension (N);
      Eval_Slice (N);
   end Resolve_Slice;

   ----------------------------
   -- Resolve_String_Literal --
   ----------------------------

   procedure Resolve_String_Literal (N : Node_Id; Typ : Entity_Id) is
      C_Typ      : constant Entity_Id  := Component_Type (Typ);
      R_Typ      : constant Entity_Id  := Root_Type (C_Typ);
      Loc        : constant Source_Ptr := Sloc (N);
      Str        : constant String_Id  := Strval (N);
      Strlen     : constant Nat        := String_Length (Str);
      Subtype_Id : Entity_Id;
      Need_Check : Boolean;

   begin
      --  For a string appearing in a concatenation, defer creation of the
      --  string_literal_subtype until the end of the resolution of the
      --  concatenation, because the literal may be constant-folded away. This
      --  is a useful optimization for long concatenation expressions.

      --  If the string is an aggregate built for a single character (which
      --  happens in a non-static context) or a is null string to which special
      --  checks may apply, we build the subtype. Wide strings must also get a
      --  string subtype if they come from a one character aggregate. Strings
      --  generated by attributes might be static, but it is often hard to
      --  determine whether the enclosing context is static, so we generate
      --  subtypes for them as well, thus losing some rarer optimizations ???
      --  Same for strings that come from a static conversion.

      Need_Check :=
        (Strlen = 0 and then Typ /= Standard_String)
          or else Nkind (Parent (N)) /= N_Op_Concat
          or else (N /= Left_Opnd (Parent (N))
                    and then N /= Right_Opnd (Parent (N)))
          or else ((Typ = Standard_Wide_String
                      or else Typ = Standard_Wide_Wide_String)
                    and then Nkind (Original_Node (N)) /= N_String_Literal);

      --  If the resolving type is itself a string literal subtype, we can just
      --  reuse it, since there is no point in creating another.

      if Ekind (Typ) = E_String_Literal_Subtype then
         Subtype_Id := Typ;

      elsif Nkind (Parent (N)) = N_Op_Concat
        and then not Need_Check
        and then not Nkind_In (Original_Node (N), N_Character_Literal,
                                                  N_Attribute_Reference,
                                                  N_Qualified_Expression,
                                                  N_Type_Conversion)
      then
         Subtype_Id := Typ;

      --  Do not generate a string literal subtype for the default expression
      --  of a formal parameter in GNATprove mode. This is because the string
      --  subtype is associated with the freezing actions of the subprogram,
      --  however freezing is disabled in GNATprove mode and as a result the
      --  subtype is unavailable.

      elsif GNATprove_Mode
        and then Nkind (Parent (N)) = N_Parameter_Specification
      then
         Subtype_Id := Typ;

      --  Otherwise we must create a string literal subtype. Note that the
      --  whole idea of string literal subtypes is simply to avoid the need
      --  for building a full fledged array subtype for each literal.

      else
         Set_String_Literal_Subtype (N, Typ);
         Subtype_Id := Etype (N);
      end if;

      if Nkind (Parent (N)) /= N_Op_Concat
        or else Need_Check
      then
         Set_Etype (N, Subtype_Id);
         Eval_String_Literal (N);
      end if;

      if Is_Limited_Composite (Typ)
        or else Is_Private_Composite (Typ)
      then
         Error_Msg_N ("string literal not available for private array", N);
         Set_Etype (N, Any_Type);
         return;
      end if;

      --  The validity of a null string has been checked in the call to
      --  Eval_String_Literal.

      if Strlen = 0 then
         return;

      --  Always accept string literal with component type Any_Character, which
      --  occurs in error situations and in comparisons of literals, both of
      --  which should accept all literals.

      elsif R_Typ = Any_Character then
         return;

      --  If the type is bit-packed, then we always transform the string
      --  literal into a full fledged aggregate.

      elsif Is_Bit_Packed_Array (Typ) then
         null;

      --  Deal with cases of Wide_Wide_String, Wide_String, and String

      else
         --  For Standard.Wide_Wide_String, or any other type whose component
         --  type is Standard.Wide_Wide_Character, we know that all the
         --  characters in the string must be acceptable, since the parser
         --  accepted the characters as valid character literals.

         if R_Typ = Standard_Wide_Wide_Character then
            null;

         --  For the case of Standard.String, or any other type whose component
         --  type is Standard.Character, we must make sure that there are no
         --  wide characters in the string, i.e. that it is entirely composed
         --  of characters in range of type Character.

         --  If the string literal is the result of a static concatenation, the
         --  test has already been performed on the components, and need not be
         --  repeated.

         elsif R_Typ = Standard_Character
           and then Nkind (Original_Node (N)) /= N_Op_Concat
         then
            for J in 1 .. Strlen loop
               if not In_Character_Range (Get_String_Char (Str, J)) then

                  --  If we are out of range, post error. This is one of the
                  --  very few places that we place the flag in the middle of
                  --  a token, right under the offending wide character. Not
                  --  quite clear if this is right wrt wide character encoding
                  --  sequences, but it's only an error message.

                  Error_Msg
                    ("literal out of range of type Standard.Character",
                     Source_Ptr (Int (Loc) + J));
                  return;
               end if;
            end loop;

         --  For the case of Standard.Wide_String, or any other type whose
         --  component type is Standard.Wide_Character, we must make sure that
         --  there are no wide characters in the string, i.e. that it is
         --  entirely composed of characters in range of type Wide_Character.

         --  If the string literal is the result of a static concatenation,
         --  the test has already been performed on the components, and need
         --  not be repeated.

         elsif R_Typ = Standard_Wide_Character
           and then Nkind (Original_Node (N)) /= N_Op_Concat
         then
            for J in 1 .. Strlen loop
               if not In_Wide_Character_Range (Get_String_Char (Str, J)) then

                  --  If we are out of range, post error. This is one of the
                  --  very few places that we place the flag in the middle of
                  --  a token, right under the offending wide character.

                  --  This is not quite right, because characters in general
                  --  will take more than one character position ???

                  Error_Msg
                    ("literal out of range of type Standard.Wide_Character",
                     Source_Ptr (Int (Loc) + J));
                  return;
               end if;
            end loop;

         --  If the root type is not a standard character, then we will convert
         --  the string into an aggregate and will let the aggregate code do
         --  the checking. Standard Wide_Wide_Character is also OK here.

         else
            null;
         end if;

         --  See if the component type of the array corresponding to the string
         --  has compile time known bounds. If yes we can directly check
         --  whether the evaluation of the string will raise constraint error.
         --  Otherwise we need to transform the string literal into the
         --  corresponding character aggregate and let the aggregate code do
         --  the checking. We use the same transformation if the component
         --  type has a static predicate, which will be applied to each
         --  character when the aggregate is resolved.

         if Is_Standard_Character_Type (R_Typ) then

            --  Check for the case of full range, where we are definitely OK

            if Component_Type (Typ) = Base_Type (Component_Type (Typ)) then
               return;
            end if;

            --  Here the range is not the complete base type range, so check

            declare
               Comp_Typ_Lo : constant Node_Id :=
                               Type_Low_Bound (Component_Type (Typ));
               Comp_Typ_Hi : constant Node_Id :=
                               Type_High_Bound (Component_Type (Typ));

               Char_Val : Uint;

            begin
               if Compile_Time_Known_Value (Comp_Typ_Lo)
                 and then Compile_Time_Known_Value (Comp_Typ_Hi)
               then
                  for J in 1 .. Strlen loop
                     Char_Val := UI_From_Int (Int (Get_String_Char (Str, J)));

                     if Char_Val < Expr_Value (Comp_Typ_Lo)
                       or else Char_Val > Expr_Value (Comp_Typ_Hi)
                     then
                        Apply_Compile_Time_Constraint_Error
                          (N, "character out of range??",
                           CE_Range_Check_Failed,
                           Loc => Source_Ptr (Int (Loc) + J));
                     end if;
                  end loop;

                  if not Has_Static_Predicate (C_Typ) then
                     return;
                  end if;
               end if;
            end;
         end if;
      end if;

      --  If we got here we meed to transform the string literal into the
      --  equivalent qualified positional array aggregate. This is rather
      --  heavy artillery for this situation, but it is hard work to avoid.

      declare
         Lits : constant List_Id    := New_List;
         P    : Source_Ptr := Loc + 1;
         C    : Char_Code;

      begin
         --  Build the character literals, we give them source locations that
         --  correspond to the string positions, which is a bit tricky given
         --  the possible presence of wide character escape sequences.

         for J in 1 .. Strlen loop
            C := Get_String_Char (Str, J);
            Set_Character_Literal_Name (C);

            Append_To (Lits,
              Make_Character_Literal (P,
                Chars              => Name_Find,
                Char_Literal_Value => UI_From_CC (C)));

            if In_Character_Range (C) then
               P := P + 1;

            --  Should we have a call to Skip_Wide here ???

            --  ???     else
            --             Skip_Wide (P);

            end if;
         end loop;

         Rewrite (N,
           Make_Qualified_Expression (Loc,
             Subtype_Mark => New_Occurrence_Of (Typ, Loc),
             Expression   =>
               Make_Aggregate (Loc, Expressions => Lits)));

         Analyze_And_Resolve (N, Typ);
      end;
   end Resolve_String_Literal;

   -------------------------
   -- Resolve_Target_Name --
   -------------------------

   procedure Resolve_Target_Name (N : Node_Id; Typ : Entity_Id) is
   begin
      Set_Etype (N, Typ);
   end Resolve_Target_Name;

   -----------------------------
   -- Resolve_Type_Conversion --
   -----------------------------

   procedure Resolve_Type_Conversion (N : Node_Id; Typ : Entity_Id) is
      Conv_OK     : constant Boolean   := Conversion_OK (N);
      Operand     : constant Node_Id   := Expression (N);
      Operand_Typ : constant Entity_Id := Etype (Operand);
      Target_Typ  : constant Entity_Id := Etype (N);
      Rop         : Node_Id;
      Orig_N      : Node_Id;
      Orig_T      : Node_Id;

      Test_Redundant : Boolean := Warn_On_Redundant_Constructs;
      --  Set to False to suppress cases where we want to suppress the test
      --  for redundancy to avoid possible false positives on this warning.

   begin
      if not Conv_OK
        and then not Valid_Conversion (N, Target_Typ, Operand)
      then
         return;
      end if;

      --  If the Operand Etype is Universal_Fixed, then the conversion is
      --  never redundant. We need this check because by the time we have
      --  finished the rather complex transformation, the conversion looks
      --  redundant when it is not.

      if Operand_Typ = Universal_Fixed then
         Test_Redundant := False;

      --  If the operand is marked as Any_Fixed, then special processing is
      --  required. This is also a case where we suppress the test for a
      --  redundant conversion, since most certainly it is not redundant.

      elsif Operand_Typ = Any_Fixed then
         Test_Redundant := False;

         --  Mixed-mode operation involving a literal. Context must be a fixed
         --  type which is applied to the literal subsequently.

         --  Multiplication and division involving two fixed type operands must
         --  yield a universal real because the result is computed in arbitrary
         --  precision.

         if Is_Fixed_Point_Type (Typ)
           and then Nkind_In (Operand, N_Op_Divide, N_Op_Multiply)
           and then Etype (Left_Opnd  (Operand)) = Any_Fixed
           and then Etype (Right_Opnd (Operand)) = Any_Fixed
         then
            Set_Etype (Operand, Universal_Real);

         elsif Is_Numeric_Type (Typ)
           and then Nkind_In (Operand, N_Op_Multiply, N_Op_Divide)
           and then (Etype (Right_Opnd (Operand)) = Universal_Real
                       or else
                     Etype (Left_Opnd  (Operand)) = Universal_Real)
         then
            --  Return if expression is ambiguous

            if Unique_Fixed_Point_Type (N) = Any_Type then
               return;

            --  If nothing else, the available fixed type is Duration

            else
               Set_Etype (Operand, Standard_Duration);
            end if;

            --  Resolve the real operand with largest available precision

            if Etype (Right_Opnd (Operand)) = Universal_Real then
               Rop := New_Copy_Tree (Right_Opnd (Operand));
            else
               Rop := New_Copy_Tree (Left_Opnd (Operand));
            end if;

            Resolve (Rop, Universal_Real);

            --  If the operand is a literal (it could be a non-static and
            --  illegal exponentiation) check whether the use of Duration
            --  is potentially inaccurate.

            if Nkind (Rop) = N_Real_Literal
              and then Realval (Rop) /= Ureal_0
              and then abs (Realval (Rop)) < Delta_Value (Standard_Duration)
            then
               Error_Msg_N
                 ("??universal real operand can only "
                  & "be interpreted as Duration!", Rop);
               Error_Msg_N
                 ("\??precision will be lost in the conversion!", Rop);
            end if;

         elsif Is_Numeric_Type (Typ)
           and then Nkind (Operand) in N_Op
           and then Unique_Fixed_Point_Type (N) /= Any_Type
         then
            Set_Etype (Operand, Standard_Duration);

         else
            Error_Msg_N ("invalid context for mixed mode operation", N);
            Set_Etype (Operand, Any_Type);
            return;
         end if;
      end if;

      Resolve (Operand);

      --  In SPARK, a type conversion between array types should be restricted
      --  to types which have matching static bounds.

      --  Protect call to Matching_Static_Array_Bounds to avoid costly
      --  operation if not needed.

      if Restriction_Check_Required (SPARK_05)
        and then Is_Array_Type (Target_Typ)
        and then Is_Array_Type (Operand_Typ)
        and then Operand_Typ /= Any_Composite  --  or else Operand in error
        and then not Matching_Static_Array_Bounds (Target_Typ, Operand_Typ)
      then
         Check_SPARK_05_Restriction
           ("array types should have matching static bounds", N);
      end if;

      --  In formal mode, the operand of an ancestor type conversion must be an
      --  object (not an expression).

      if Is_Tagged_Type (Target_Typ)
        and then not Is_Class_Wide_Type (Target_Typ)
        and then Is_Tagged_Type (Operand_Typ)
        and then not Is_Class_Wide_Type (Operand_Typ)
        and then Is_Ancestor (Target_Typ, Operand_Typ)
        and then not Is_SPARK_05_Object_Reference (Operand)
      then
         Check_SPARK_05_Restriction ("object required", Operand);
      end if;

      Analyze_Dimension (N);

      --  Note: we do the Eval_Type_Conversion call before applying the
      --  required checks for a subtype conversion. This is important, since
      --  both are prepared under certain circumstances to change the type
      --  conversion to a constraint error node, but in the case of
      --  Eval_Type_Conversion this may reflect an illegality in the static
      --  case, and we would miss the illegality (getting only a warning
      --  message), if we applied the type conversion checks first.

      Eval_Type_Conversion (N);

      --  Even when evaluation is not possible, we may be able to simplify the
      --  conversion or its expression. This needs to be done before applying
      --  checks, since otherwise the checks may use the original expression
      --  and defeat the simplifications. This is specifically the case for
      --  elimination of the floating-point Truncation attribute in
      --  float-to-int conversions.

      Simplify_Type_Conversion (N);

      --  If after evaluation we still have a type conversion, then we may need
      --  to apply checks required for a subtype conversion.

      --  Skip these type conversion checks if universal fixed operands
      --  operands involved, since range checks are handled separately for
      --  these cases (in the appropriate Expand routines in unit Exp_Fixd).

      if Nkind (N) = N_Type_Conversion
        and then not Is_Generic_Type (Root_Type (Target_Typ))
        and then Target_Typ  /= Universal_Fixed
        and then Operand_Typ /= Universal_Fixed
      then
         Apply_Type_Conversion_Checks (N);
      end if;

      --  Issue warning for conversion of simple object to its own type. We
      --  have to test the original nodes, since they may have been rewritten
      --  by various optimizations.

      Orig_N := Original_Node (N);

      --  Here we test for a redundant conversion if the warning mode is
      --  active (and was not locally reset), and we have a type conversion
      --  from source not appearing in a generic instance.

      if Test_Redundant
        and then Nkind (Orig_N) = N_Type_Conversion
        and then Comes_From_Source (Orig_N)
        and then not In_Instance
      then
         Orig_N := Original_Node (Expression (Orig_N));
         Orig_T := Target_Typ;

         --  If the node is part of a larger expression, the Target_Type
         --  may not be the original type of the node if the context is a
         --  condition. Recover original type to see if conversion is needed.

         if Is_Boolean_Type (Orig_T)
          and then Nkind (Parent (N)) in N_Op
         then
            Orig_T := Etype (Parent (N));
         end if;

         --  If we have an entity name, then give the warning if the entity
         --  is the right type, or if it is a loop parameter covered by the
         --  original type (that's needed because loop parameters have an
         --  odd subtype coming from the bounds).

         if (Is_Entity_Name (Orig_N)
              and then
                (Etype (Entity (Orig_N)) = Orig_T
                  or else
                    (Ekind (Entity (Orig_N)) = E_Loop_Parameter
                      and then Covers (Orig_T, Etype (Entity (Orig_N))))))

           --  If not an entity, then type of expression must match

           or else Etype (Orig_N) = Orig_T
         then
            --  One more check, do not give warning if the analyzed conversion
            --  has an expression with non-static bounds, and the bounds of the
            --  target are static. This avoids junk warnings in cases where the
            --  conversion is necessary to establish staticness, for example in
            --  a case statement.

            if not Is_OK_Static_Subtype (Operand_Typ)
              and then Is_OK_Static_Subtype (Target_Typ)
            then
               null;

            --  Finally, if this type conversion occurs in a context requiring
            --  a prefix, and the expression is a qualified expression then the
            --  type conversion is not redundant, since a qualified expression
            --  is not a prefix, whereas a type conversion is. For example, "X
            --  := T'(Funx(...)).Y;" is illegal because a selected component
            --  requires a prefix, but a type conversion makes it legal: "X :=
            --  T(T'(Funx(...))).Y;"

            --  In Ada 2012, a qualified expression is a name, so this idiom is
            --  no longer needed, but we still suppress the warning because it
            --  seems unfriendly for warnings to pop up when you switch to the
            --  newer language version.

            elsif Nkind (Orig_N) = N_Qualified_Expression
              and then Nkind_In (Parent (N), N_Attribute_Reference,
                                             N_Indexed_Component,
                                             N_Selected_Component,
                                             N_Slice,
                                             N_Explicit_Dereference)
            then
               null;

            --  Never warn on conversion to Long_Long_Integer'Base since
            --  that is most likely an artifact of the extended overflow
            --  checking and comes from complex expanded code.

            elsif Orig_T = Base_Type (Standard_Long_Long_Integer) then
               null;

            --  Here we give the redundant conversion warning. If it is an
            --  entity, give the name of the entity in the message. If not,
            --  just mention the expression.

            --  Shoudn't we test Warn_On_Redundant_Constructs here ???

            else
               if Is_Entity_Name (Orig_N) then
                  Error_Msg_Node_2 := Orig_T;
                  Error_Msg_NE -- CODEFIX
                    ("??redundant conversion, & is of type &!",
                     N, Entity (Orig_N));
               else
                  Error_Msg_NE
                    ("??redundant conversion, expression is of type&!",
                     N, Orig_T);
               end if;
            end if;
         end if;
      end if;

      --  Ada 2005 (AI-251): Handle class-wide interface type conversions.
      --  No need to perform any interface conversion if the type of the
      --  expression coincides with the target type.

      if Ada_Version >= Ada_2005
        and then Expander_Active
        and then Operand_Typ /= Target_Typ
      then
         declare
            Opnd   : Entity_Id := Operand_Typ;
            Target : Entity_Id := Target_Typ;

         begin
            --  If the type of the operand is a limited view, use nonlimited
            --  view when available. If it is a class-wide type, recover the
            --  class-wide type of the nonlimited view.

            if From_Limited_With (Opnd)
              and then Has_Non_Limited_View (Opnd)
            then
               Opnd := Non_Limited_View (Opnd);
               Set_Etype (Expression (N), Opnd);
            end if;

            --  It seems that Non_Limited_View should also be applied for
            --  Target when it has a limited view, but that leads to missing
            --  error checks on interface conversions further below. ???

            if Is_Access_Type (Opnd) then
               Opnd := Designated_Type (Opnd);

               --  If the type of the operand is a limited view, use nonlimited
               --  view when available. If it is a class-wide type, recover the
               --  class-wide type of the nonlimited view.

               if From_Limited_With (Opnd)
                 and then Has_Non_Limited_View (Opnd)
               then
                  Opnd := Non_Limited_View (Opnd);
               end if;
            end if;

            if Is_Access_Type (Target_Typ) then
               Target := Designated_Type (Target);

               --  If the target type is a limited view, use nonlimited view
               --  when available.

               if From_Limited_With (Target)
                 and then Has_Non_Limited_View (Target)
               then
                  Target := Non_Limited_View (Target);
               end if;
            end if;

            if Opnd = Target then
               null;

            --  Conversion from interface type

            --  It seems that it would be better for the error checks below
            --  to be performed as part of Validate_Conversion (and maybe some
            --  of the error checks above could be moved as well?). ???

            elsif Is_Interface (Opnd) then

               --  Ada 2005 (AI-217): Handle entities from limited views

               if From_Limited_With (Opnd) then
                  Error_Msg_Qual_Level := 99;
                  Error_Msg_NE -- CODEFIX
                    ("missing WITH clause on package &", N,
                    Cunit_Entity (Get_Source_Unit (Base_Type (Opnd))));
                  Error_Msg_N
                    ("type conversions require visibility of the full view",
                     N);

               elsif From_Limited_With (Target)
                 and then not
                   (Is_Access_Type (Target_Typ)
                      and then Present (Non_Limited_View (Etype (Target))))
               then
                  Error_Msg_Qual_Level := 99;
                  Error_Msg_NE -- CODEFIX
                    ("missing WITH clause on package &", N,
                    Cunit_Entity (Get_Source_Unit (Base_Type (Target))));
                  Error_Msg_N
                    ("type conversions require visibility of the full view",
                     N);

               else
                  Expand_Interface_Conversion (N);
               end if;

            --  Conversion to interface type

            elsif Is_Interface (Target) then

               --  Handle subtypes

               if Ekind_In (Opnd, E_Protected_Subtype, E_Task_Subtype) then
                  Opnd := Etype (Opnd);
               end if;

               if Is_Class_Wide_Type (Opnd)
                 or else Interface_Present_In_Ancestor
                           (Typ   => Opnd,
                            Iface => Target)
               then
                  Expand_Interface_Conversion (N);
               else
                  Error_Msg_Name_1 := Chars (Etype (Target));
                  Error_Msg_Name_2 := Chars (Opnd);
                  Error_Msg_N
                    ("wrong interface conversion (% is not a progenitor "
                     & "of %)", N);
               end if;
            end if;
         end;
      end if;

      --  Ada 2012: once the type conversion is resolved, check whether the
      --  operand statisfies the static predicate of the target type.

      if Has_Predicates (Target_Typ) then
         Check_Expression_Against_Static_Predicate (N, Target_Typ);
      end if;

      --  If at this stage we have a real to integer conversion, make sure that
      --  the Do_Range_Check flag is set, because such conversions in general
      --  need a range check. We only need this if expansion is off.
      --  In GNATprove mode, we only do that when converting from fixed-point
      --  (as floating-point to integer conversions are now handled in
      --  GNATprove mode).

      if Nkind (N) = N_Type_Conversion
        and then not Expander_Active
        and then Is_Integer_Type (Target_Typ)
        and then (Is_Fixed_Point_Type (Operand_Typ)
                   or else (not GNATprove_Mode
                             and then Is_Floating_Point_Type (Operand_Typ)))
        and then not Range_Checks_Suppressed (Target_Typ)
        and then not Range_Checks_Suppressed (Operand_Typ)
      then
         Set_Do_Range_Check (Operand);
      end if;

      --  Generating C code a type conversion of an access to constrained
      --  array type to access to unconstrained array type involves building
      --  a fat pointer which in general cannot be generated on the fly. We
      --  remove side effects in order to store the result of the conversion
      --  into a temporary.

      if Modify_Tree_For_C
        and then Nkind (N) = N_Type_Conversion
        and then Nkind (Parent (N)) /= N_Object_Declaration
        and then Is_Access_Type (Etype (N))
        and then Is_Array_Type (Designated_Type (Etype (N)))
        and then not Is_Constrained (Designated_Type (Etype (N)))
        and then Is_Constrained (Designated_Type (Etype (Expression (N))))
      then
         Remove_Side_Effects (N);
      end if;
   end Resolve_Type_Conversion;

   ----------------------
   -- Resolve_Unary_Op --
   ----------------------

   procedure Resolve_Unary_Op (N : Node_Id; Typ : Entity_Id) is
      B_Typ : constant Entity_Id := Base_Type (Typ);
      R     : constant Node_Id   := Right_Opnd (N);
      OK    : Boolean;
      Lo    : Uint;
      Hi    : Uint;

   begin
      if Is_Modular_Integer_Type (Typ) and then Nkind (N) /= N_Op_Not then
         Error_Msg_Name_1 := Chars (Typ);
         Check_SPARK_05_Restriction
           ("unary operator not defined for modular type%", N);
      end if;

      --  Deal with intrinsic unary operators

      if Comes_From_Source (N)
        and then Ekind (Entity (N)) = E_Function
        and then Is_Imported (Entity (N))
        and then Is_Intrinsic_Subprogram (Entity (N))
      then
         Resolve_Intrinsic_Unary_Operator (N, Typ);
         return;
      end if;

      --  Deal with universal cases

      if Etype (R) = Universal_Integer
           or else
         Etype (R) = Universal_Real
      then
         Check_For_Visible_Operator (N, B_Typ);
      end if;

      Set_Etype (N, B_Typ);
      Resolve (R, B_Typ);

      --  Generate warning for expressions like abs (x mod 2)

      if Warn_On_Redundant_Constructs
        and then Nkind (N) = N_Op_Abs
      then
         Determine_Range (Right_Opnd (N), OK, Lo, Hi);

         if OK and then Hi >= Lo and then Lo >= 0 then
            Error_Msg_N -- CODEFIX
             ("?r?abs applied to known non-negative value has no effect", N);
         end if;
      end if;

      --  Deal with reference generation

      Check_Unset_Reference (R);
      Generate_Operator_Reference (N, B_Typ);
      Analyze_Dimension (N);
      Eval_Unary_Op (N);

      --  Set overflow checking bit. Much cleverer code needed here eventually
      --  and perhaps the Resolve routines should be separated for the various
      --  arithmetic operations, since they will need different processing ???

      if Nkind (N) in N_Op then
         if not Overflow_Checks_Suppressed (Etype (N)) then
            Enable_Overflow_Check (N);
         end if;
      end if;

      --  Generate warning for expressions like -5 mod 3 for integers. No need
      --  to worry in the floating-point case, since parens do not affect the
      --  result so there is no point in giving in a warning.

      declare
         Norig : constant Node_Id := Original_Node (N);
         Rorig : Node_Id;
         Val   : Uint;
         HB    : Uint;
         LB    : Uint;
         Lval  : Uint;
         Opnd  : Node_Id;

      begin
         if Warn_On_Questionable_Missing_Parens
           and then Comes_From_Source (Norig)
           and then Is_Integer_Type (Typ)
           and then Nkind (Norig) = N_Op_Minus
         then
            Rorig := Original_Node (Right_Opnd (Norig));

            --  We are looking for cases where the right operand is not
            --  parenthesized, and is a binary operator, multiply, divide, or
            --  mod. These are the cases where the grouping can affect results.

            if Paren_Count (Rorig) = 0
              and then Nkind_In (Rorig, N_Op_Mod, N_Op_Multiply, N_Op_Divide)
            then
               --  For mod, we always give the warning, since the value is
               --  affected by the parenthesization (e.g. (-5) mod 315 /=
               --  -(5 mod 315)). But for the other cases, the only concern is
               --  overflow, e.g. for the case of 8 big signed (-(2 * 64)
               --  overflows, but (-2) * 64 does not). So we try to give the
               --  message only when overflow is possible.

               if Nkind (Rorig) /= N_Op_Mod
                 and then Compile_Time_Known_Value (R)
               then
                  Val := Expr_Value (R);

                  if Compile_Time_Known_Value (Type_High_Bound (Typ)) then
                     HB := Expr_Value (Type_High_Bound (Typ));
                  else
                     HB := Expr_Value (Type_High_Bound (Base_Type (Typ)));
                  end if;

                  if Compile_Time_Known_Value (Type_Low_Bound (Typ)) then
                     LB := Expr_Value (Type_Low_Bound (Typ));
                  else
                     LB := Expr_Value (Type_Low_Bound (Base_Type (Typ)));
                  end if;

                  --  Note that the test below is deliberately excluding the
                  --  largest negative number, since that is a potentially
                  --  troublesome case (e.g. -2 * x, where the result is the
                  --  largest negative integer has an overflow with 2 * x).

                  if Val > LB and then Val <= HB then
                     return;
                  end if;
               end if;

               --  For the multiplication case, the only case we have to worry
               --  about is when (-a)*b is exactly the largest negative number
               --  so that -(a*b) can cause overflow. This can only happen if
               --  a is a power of 2, and more generally if any operand is a
               --  constant that is not a power of 2, then the parentheses
               --  cannot affect whether overflow occurs. We only bother to
               --  test the left most operand

               --  Loop looking at left operands for one that has known value

               Opnd := Rorig;
               Opnd_Loop : while Nkind (Opnd) = N_Op_Multiply loop
                  if Compile_Time_Known_Value (Left_Opnd (Opnd)) then
                     Lval := UI_Abs (Expr_Value (Left_Opnd (Opnd)));

                     --  Operand value of 0 or 1 skips warning

                     if Lval <= 1 then
                        return;

                     --  Otherwise check power of 2, if power of 2, warn, if
                     --  anything else, skip warning.

                     else
                        while Lval /= 2 loop
                           if Lval mod 2 = 1 then
                              return;
                           else
                              Lval := Lval / 2;
                           end if;
                        end loop;

                        exit Opnd_Loop;
                     end if;
                  end if;

                  --  Keep looking at left operands

                  Opnd := Left_Opnd (Opnd);
               end loop Opnd_Loop;

               --  For rem or "/" we can only have a problematic situation
               --  if the divisor has a value of minus one or one. Otherwise
               --  overflow is impossible (divisor > 1) or we have a case of
               --  division by zero in any case.

               if Nkind_In (Rorig, N_Op_Divide, N_Op_Rem)
                 and then Compile_Time_Known_Value (Right_Opnd (Rorig))
                 and then UI_Abs (Expr_Value (Right_Opnd (Rorig))) /= 1
               then
                  return;
               end if;

               --  If we fall through warning should be issued

               --  Shouldn't we test Warn_On_Questionable_Missing_Parens ???

               Error_Msg_N
                 ("??unary minus expression should be parenthesized here!", N);
            end if;
         end if;
      end;
   end Resolve_Unary_Op;

   ----------------------------------
   -- Resolve_Unchecked_Expression --
   ----------------------------------

   procedure Resolve_Unchecked_Expression
     (N   : Node_Id;
      Typ : Entity_Id)
   is
   begin
      Resolve (Expression (N), Typ, Suppress => All_Checks);
      Set_Etype (N, Typ);
   end Resolve_Unchecked_Expression;

   ---------------------------------------
   -- Resolve_Unchecked_Type_Conversion --
   ---------------------------------------

   procedure Resolve_Unchecked_Type_Conversion
     (N   : Node_Id;
      Typ : Entity_Id)
   is
      pragma Warnings (Off, Typ);

      Operand   : constant Node_Id   := Expression (N);
      Opnd_Type : constant Entity_Id := Etype (Operand);

   begin
      --  Resolve operand using its own type

      Resolve (Operand, Opnd_Type);

      --  In an inlined context, the unchecked conversion may be applied
      --  to a literal, in which case its type is the type of the context.
      --  (In other contexts conversions cannot apply to literals).

      if In_Inlined_Body
        and then (Opnd_Type = Any_Character or else
                  Opnd_Type = Any_Integer   or else
                  Opnd_Type = Any_Real)
      then
         Set_Etype (Operand, Typ);
      end if;

      Analyze_Dimension (N);
      Eval_Unchecked_Conversion (N);
   end Resolve_Unchecked_Type_Conversion;

   ------------------------------
   -- Rewrite_Operator_As_Call --
   ------------------------------

   procedure Rewrite_Operator_As_Call (N : Node_Id; Nam : Entity_Id) is
      Loc     : constant Source_Ptr := Sloc (N);
      Actuals : constant List_Id    := New_List;
      New_N   : Node_Id;

   begin
      if Nkind (N) in N_Binary_Op then
         Append (Left_Opnd (N), Actuals);
      end if;

      Append (Right_Opnd (N), Actuals);

      New_N :=
        Make_Function_Call (Sloc => Loc,
          Name => New_Occurrence_Of (Nam, Loc),
          Parameter_Associations => Actuals);

      Preserve_Comes_From_Source (New_N, N);
      Preserve_Comes_From_Source (Name (New_N), N);
      Rewrite (N, New_N);
      Set_Etype (N, Etype (Nam));
   end Rewrite_Operator_As_Call;

   ------------------------------
   -- Rewrite_Renamed_Operator --
   ------------------------------

   procedure Rewrite_Renamed_Operator
     (N   : Node_Id;
      Op  : Entity_Id;
      Typ : Entity_Id)
   is
      Nam       : constant Name_Id := Chars (Op);
      Is_Binary : constant Boolean := Nkind (N) in N_Binary_Op;
      Op_Node   : Node_Id;

   begin
      --  Do not perform this transformation within a pre/postcondition,
      --  because the expression will be reanalyzed, and the transformation
      --  might affect the visibility of the operator, e.g. in an instance.
      --  Note that fully analyzed and expanded pre/postconditions appear as
      --  pragma Check equivalents.

      if In_Pre_Post_Condition (N) then
         return;
      end if;

      --  Likewise when an expression function is being preanalyzed, since the
      --  expression will be reanalyzed as part of the generated body.

      if In_Spec_Expression then
         declare
            S : constant Entity_Id := Current_Scope_No_Loops;
         begin
            if Ekind (S) = E_Function
              and then Nkind (Original_Node (Unit_Declaration_Node (S))) =
                         N_Expression_Function
            then
               return;
            end if;
         end;
      end if;

      --  Rewrite the operator node using the real operator, not its renaming.
      --  Exclude user-defined intrinsic operations of the same name, which are
      --  treated separately and rewritten as calls.

      if Ekind (Op) /= E_Function or else Chars (N) /= Nam then
         Op_Node := New_Node (Operator_Kind (Nam, Is_Binary), Sloc (N));
         Set_Chars      (Op_Node, Nam);
         Set_Etype      (Op_Node, Etype (N));
         Set_Entity     (Op_Node, Op);
         Set_Right_Opnd (Op_Node, Right_Opnd (N));

         --  Indicate that both the original entity and its renaming are
         --  referenced at this point.

         Generate_Reference (Entity (N), N);
         Generate_Reference (Op, N);

         if Is_Binary then
            Set_Left_Opnd (Op_Node, Left_Opnd (N));
         end if;

         Rewrite (N, Op_Node);

         --  If the context type is private, add the appropriate conversions so
         --  that the operator is applied to the full view. This is done in the
         --  routines that resolve intrinsic operators.

         if Is_Intrinsic_Subprogram (Op) and then Is_Private_Type (Typ) then
            case Nkind (N) is
               when N_Op_Add
                  | N_Op_Divide
                  | N_Op_Expon
                  | N_Op_Mod
                  | N_Op_Multiply
                  | N_Op_Rem
                  | N_Op_Subtract
               =>
                  Resolve_Intrinsic_Operator (N, Typ);

               when N_Op_Abs
                  | N_Op_Minus
                  | N_Op_Plus
               =>
                  Resolve_Intrinsic_Unary_Operator (N, Typ);

               when others =>
                  Resolve (N, Typ);
            end case;
         end if;

      elsif Ekind (Op) = E_Function and then Is_Intrinsic_Subprogram (Op) then

         --  Operator renames a user-defined operator of the same name. Use the
         --  original operator in the node, which is the one Gigi knows about.

         Set_Entity (N, Op);
         Set_Is_Overloaded (N, False);
      end if;
   end Rewrite_Renamed_Operator;

   -----------------------
   -- Set_Slice_Subtype --
   -----------------------

   --  Build an implicit subtype declaration to represent the type delivered by
   --  the slice. This is an abbreviated version of an array subtype. We define
   --  an index subtype for the slice, using either the subtype name or the
   --  discrete range of the slice. To be consistent with index usage elsewhere
   --  we create a list header to hold the single index. This list is not
   --  otherwise attached to the syntax tree.

   procedure Set_Slice_Subtype (N : Node_Id) is
      Loc           : constant Source_Ptr := Sloc (N);
      Index_List    : constant List_Id    := New_List;
      Index         : Node_Id;
      Index_Subtype : Entity_Id;
      Index_Type    : Entity_Id;
      Slice_Subtype : Entity_Id;
      Drange        : constant Node_Id := Discrete_Range (N);

   begin
      Index_Type := Base_Type (Etype (Drange));

      if Is_Entity_Name (Drange) then
         Index_Subtype := Entity (Drange);

      else
         --  We force the evaluation of a range. This is definitely needed in
         --  the renamed case, and seems safer to do unconditionally. Note in
         --  any case that since we will create and insert an Itype referring
         --  to this range, we must make sure any side effect removal actions
         --  are inserted before the Itype definition.

         if Nkind (Drange) = N_Range then
            Force_Evaluation (Low_Bound (Drange));
            Force_Evaluation (High_Bound (Drange));

         --  If the discrete range is given by a subtype indication, the
         --  type of the slice is the base of the subtype mark.

         elsif Nkind (Drange) = N_Subtype_Indication then
            declare
               R : constant Node_Id := Range_Expression (Constraint (Drange));
            begin
               Index_Type := Base_Type (Entity (Subtype_Mark (Drange)));
               Force_Evaluation (Low_Bound  (R));
               Force_Evaluation (High_Bound (R));
            end;
         end if;

         Index_Subtype := Create_Itype (Subtype_Kind (Ekind (Index_Type)), N);

         --  Take a new copy of Drange (where bounds have been rewritten to
         --  reference side-effect-free names). Using a separate tree ensures
         --  that further expansion (e.g. while rewriting a slice assignment
         --  into a FOR loop) does not attempt to remove side effects on the
         --  bounds again (which would cause the bounds in the index subtype
         --  definition to refer to temporaries before they are defined) (the
         --  reason is that some names are considered side effect free here
         --  for the subtype, but not in the context of a loop iteration
         --  scheme).

         Set_Scalar_Range   (Index_Subtype, New_Copy_Tree (Drange));
         Set_Parent         (Scalar_Range (Index_Subtype), Index_Subtype);
         Set_Etype          (Index_Subtype, Index_Type);
         Set_Size_Info      (Index_Subtype, Index_Type);
         Set_RM_Size        (Index_Subtype, RM_Size (Index_Type));
         Set_Is_Constrained (Index_Subtype);
      end if;

      Slice_Subtype := Create_Itype (E_Array_Subtype, N);

      Index := New_Occurrence_Of (Index_Subtype, Loc);
      Set_Etype (Index, Index_Subtype);
      Append (Index, Index_List);

      Set_First_Index    (Slice_Subtype, Index);
      Set_Etype          (Slice_Subtype, Base_Type (Etype (N)));
      Set_Is_Constrained (Slice_Subtype, True);

      Check_Compile_Time_Size (Slice_Subtype);

      --  The Etype of the existing Slice node is reset to this slice subtype.
      --  Its bounds are obtained from its first index.

      Set_Etype (N, Slice_Subtype);

      --  For bit-packed slice subtypes, freeze immediately (except in the case
      --  of being in a "spec expression" where we never freeze when we first
      --  see the expression).

      if Is_Bit_Packed_Array (Slice_Subtype) and not In_Spec_Expression then
         Freeze_Itype (Slice_Subtype, N);

      --  For all other cases insert an itype reference in the slice's actions
      --  so that the itype is frozen at the proper place in the tree (i.e. at
      --  the point where actions for the slice are analyzed). Note that this
      --  is different from freezing the itype immediately, which might be
      --  premature (e.g. if the slice is within a transient scope). This needs
      --  to be done only if expansion is enabled.

      elsif Expander_Active then
         Ensure_Defined (Typ => Slice_Subtype, N => N);
      end if;
   end Set_Slice_Subtype;

   --------------------------------
   -- Set_String_Literal_Subtype --
   --------------------------------

   procedure Set_String_Literal_Subtype (N : Node_Id; Typ : Entity_Id) is
      Loc        : constant Source_Ptr := Sloc (N);
      Low_Bound  : constant Node_Id :=
                     Type_Low_Bound (Etype (First_Index (Typ)));
      Subtype_Id : Entity_Id;

   begin
      if Nkind (N) /= N_String_Literal then
         return;
      end if;

      Subtype_Id := Create_Itype (E_String_Literal_Subtype, N);
      Set_String_Literal_Length (Subtype_Id, UI_From_Int
                                               (String_Length (Strval (N))));
      Set_Etype          (Subtype_Id, Base_Type (Typ));
      Set_Is_Constrained (Subtype_Id);
      Set_Etype          (N, Subtype_Id);

      --  The low bound is set from the low bound of the corresponding index
      --  type. Note that we do not store the high bound in the string literal
      --  subtype, but it can be deduced if necessary from the length and the
      --  low bound.

      if Is_OK_Static_Expression (Low_Bound) then
         Set_String_Literal_Low_Bound (Subtype_Id, Low_Bound);

      --  If the lower bound is not static we create a range for the string
      --  literal, using the index type and the known length of the literal.
      --  The index type is not necessarily Positive, so the upper bound is
      --  computed as T'Val (T'Pos (Low_Bound) + L - 1).

      else
         declare
            Index_List : constant List_Id   := New_List;
            Index_Type : constant Entity_Id := Etype (First_Index (Typ));
            High_Bound : constant Node_Id   :=
                           Make_Attribute_Reference (Loc,
                             Attribute_Name => Name_Val,
                             Prefix         =>
                               New_Occurrence_Of (Index_Type, Loc),
                             Expressions    => New_List (
                               Make_Op_Add (Loc,
                                 Left_Opnd  =>
                                   Make_Attribute_Reference (Loc,
                                     Attribute_Name => Name_Pos,
                                     Prefix         =>
                                       New_Occurrence_Of (Index_Type, Loc),
                                     Expressions    =>
                                       New_List (New_Copy_Tree (Low_Bound))),
                                 Right_Opnd =>
                                   Make_Integer_Literal (Loc,
                                     String_Length (Strval (N)) - 1))));

            Array_Subtype : Entity_Id;
            Drange        : Node_Id;
            Index         : Node_Id;
            Index_Subtype : Entity_Id;

         begin
            if Is_Integer_Type (Index_Type) then
               Set_String_Literal_Low_Bound
                 (Subtype_Id, Make_Integer_Literal (Loc, 1));

            else
               --  If the index type is an enumeration type, build bounds
               --  expression with attributes.

               Set_String_Literal_Low_Bound
                 (Subtype_Id,
                  Make_Attribute_Reference (Loc,
                    Attribute_Name => Name_First,
                    Prefix         =>
                      New_Occurrence_Of (Base_Type (Index_Type), Loc)));
               Set_Etype (String_Literal_Low_Bound (Subtype_Id), Index_Type);
            end if;

            Analyze_And_Resolve (String_Literal_Low_Bound (Subtype_Id));

            --  Build bona fide subtype for the string, and wrap it in an
            --  unchecked conversion, because the back end expects the
            --  String_Literal_Subtype to have a static lower bound.

            Index_Subtype :=
              Create_Itype (Subtype_Kind (Ekind (Index_Type)), N);
            Drange := Make_Range (Loc, New_Copy_Tree (Low_Bound), High_Bound);
            Set_Scalar_Range (Index_Subtype, Drange);
            Set_Parent (Drange, N);
            Analyze_And_Resolve (Drange, Index_Type);

            --  In this context, the Index_Type may already have a constraint,
            --  so use common base type on string subtype. The base type may
            --  be used when generating attributes of the string, for example
            --  in the context of a slice assignment.

            Set_Etype     (Index_Subtype, Base_Type (Index_Type));
            Set_Size_Info (Index_Subtype, Index_Type);
            Set_RM_Size   (Index_Subtype, RM_Size (Index_Type));

            Array_Subtype := Create_Itype (E_Array_Subtype, N);

            Index := New_Occurrence_Of (Index_Subtype, Loc);
            Set_Etype (Index, Index_Subtype);
            Append (Index, Index_List);

            Set_First_Index    (Array_Subtype, Index);
            Set_Etype          (Array_Subtype, Base_Type (Typ));
            Set_Is_Constrained (Array_Subtype, True);

            Rewrite (N,
              Make_Unchecked_Type_Conversion (Loc,
                Subtype_Mark => New_Occurrence_Of (Array_Subtype, Loc),
                Expression   => Relocate_Node (N)));
            Set_Etype (N, Array_Subtype);
         end;
      end if;
   end Set_String_Literal_Subtype;

   ------------------------------
   -- Simplify_Type_Conversion --
   ------------------------------

   procedure Simplify_Type_Conversion (N : Node_Id) is
   begin
      if Nkind (N) = N_Type_Conversion then
         declare
            Operand    : constant Node_Id   := Expression (N);
            Target_Typ : constant Entity_Id := Etype (N);
            Opnd_Typ   : constant Entity_Id := Etype (Operand);

         begin
            --  Special processing if the conversion is the expression of a
            --  Rounding or Truncation attribute reference. In this case we
            --  replace:

            --     ityp (ftyp'Rounding (x)) or ityp (ftyp'Truncation (x))

            --  by

            --     ityp (x)

            --  with the Float_Truncate flag set to False or True respectively,
            --  which is more efficient. We reuse Rounding for Machine_Rounding
            --  as System.Fat_Gen, which is a permissible behavior.

            if Is_Floating_Point_Type (Opnd_Typ)
              and then
                (Is_Integer_Type (Target_Typ)
                  or else (Is_Fixed_Point_Type (Target_Typ)
                            and then Conversion_OK (N)))
              and then Nkind (Operand) = N_Attribute_Reference
              and then Nam_In (Attribute_Name (Operand), Name_Rounding,
                                                         Name_Machine_Rounding,
                                                         Name_Truncation)
            then
               declare
                  Truncate : constant Boolean :=
                               Attribute_Name (Operand) = Name_Truncation;
               begin
                  Rewrite (Operand,
                    Relocate_Node (First (Expressions (Operand))));
                  Set_Float_Truncate (N, Truncate);
               end;
            end if;
         end;
      end if;
   end Simplify_Type_Conversion;

   -----------------------------
   -- Unique_Fixed_Point_Type --
   -----------------------------

   function Unique_Fixed_Point_Type (N : Node_Id) return Entity_Id is
      procedure Fixed_Point_Error (T1 : Entity_Id; T2 : Entity_Id);
      --  Give error messages for true ambiguity. Messages are posted on node
      --  N, and entities T1, T2 are the possible interpretations.

      -----------------------
      -- Fixed_Point_Error --
      -----------------------

      procedure Fixed_Point_Error (T1 : Entity_Id; T2 : Entity_Id) is
      begin
         Error_Msg_N ("ambiguous universal_fixed_expression", N);
         Error_Msg_NE ("\\possible interpretation as}", N, T1);
         Error_Msg_NE ("\\possible interpretation as}", N, T2);
      end Fixed_Point_Error;

      --  Local variables

      ErrN : Node_Id;
      Item : Node_Id;
      Scop : Entity_Id;
      T1   : Entity_Id;
      T2   : Entity_Id;

   --  Start of processing for Unique_Fixed_Point_Type

   begin
      --  The operations on Duration are visible, so Duration is always a
      --  possible interpretation.

      T1 := Standard_Duration;

      --  Look for fixed-point types in enclosing scopes

      Scop := Current_Scope;
      while Scop /= Standard_Standard loop
         T2 := First_Entity (Scop);
         while Present (T2) loop
            if Is_Fixed_Point_Type (T2)
              and then Current_Entity (T2) = T2
              and then Scope (Base_Type (T2)) = Scop
            then
               if Present (T1) then
                  Fixed_Point_Error (T1, T2);
                  return Any_Type;
               else
                  T1 := T2;
               end if;
            end if;

            Next_Entity (T2);
         end loop;

         Scop := Scope (Scop);
      end loop;

      --  Look for visible fixed type declarations in the context

      Item := First (Context_Items (Cunit (Current_Sem_Unit)));
      while Present (Item) loop
         if Nkind (Item) = N_With_Clause then
            Scop := Entity (Name (Item));
            T2 := First_Entity (Scop);
            while Present (T2) loop
               if Is_Fixed_Point_Type (T2)
                 and then Scope (Base_Type (T2)) = Scop
                 and then (Is_Potentially_Use_Visible (T2) or else In_Use (T2))
               then
                  if Present (T1) then
                     Fixed_Point_Error (T1, T2);
                     return Any_Type;
                  else
                     T1 := T2;
                  end if;
               end if;

               Next_Entity (T2);
            end loop;
         end if;

         Next (Item);
      end loop;

      if Nkind (N) = N_Real_Literal then
         Error_Msg_NE ("??real literal interpreted as }!", N, T1);

      else
         --  When the context is a type conversion, issue the warning on the
         --  expression of the conversion because it is the actual operation.

         if Nkind_In (N, N_Type_Conversion, N_Unchecked_Type_Conversion) then
            ErrN := Expression (N);
         else
            ErrN := N;
         end if;

         Error_Msg_NE
           ("??universal_fixed expression interpreted as }!", ErrN, T1);
      end if;

      return T1;
   end Unique_Fixed_Point_Type;

   ----------------------
   -- Valid_Conversion --
   ----------------------

   function Valid_Conversion
     (N           : Node_Id;
      Target      : Entity_Id;
      Operand     : Node_Id;
      Report_Errs : Boolean := True) return Boolean
   is
      Target_Type  : constant Entity_Id := Base_Type (Target);
      Opnd_Type    : Entity_Id          := Etype (Operand);
      Inc_Ancestor : Entity_Id;

      function Conversion_Check
        (Valid : Boolean;
         Msg   : String) return Boolean;
      --  Little routine to post Msg if Valid is False, returns Valid value

      procedure Conversion_Error_N (Msg : String; N : Node_Or_Entity_Id);
      --  If Report_Errs, then calls Errout.Error_Msg_N with its arguments

      procedure Conversion_Error_NE
        (Msg : String;
         N   : Node_Or_Entity_Id;
         E   : Node_Or_Entity_Id);
      --  If Report_Errs, then calls Errout.Error_Msg_NE with its arguments

      function In_Instance_Code return Boolean;
      --  Return True if expression is within an instance but is not in one of
      --  the actuals of the instantiation. Type conversions within an instance
      --  are not rechecked because type visbility may lead to spurious errors,
      --  but conversions in an actual for a formal object must be checked.

      function Valid_Tagged_Conversion
        (Target_Type : Entity_Id;
         Opnd_Type   : Entity_Id) return Boolean;
      --  Specifically test for validity of tagged conversions

      function Valid_Array_Conversion return Boolean;
      --  Check index and component conformance, and accessibility levels if
      --  the component types are anonymous access types (Ada 2005).

      ----------------------
      -- Conversion_Check --
      ----------------------

      function Conversion_Check
        (Valid : Boolean;
         Msg   : String) return Boolean
      is
      begin
         if not Valid

            --  A generic unit has already been analyzed and we have verified
            --  that a particular conversion is OK in that context. Since the
            --  instance is reanalyzed without relying on the relationships
            --  established during the analysis of the generic, it is possible
            --  to end up with inconsistent views of private types. Do not emit
            --  the error message in such cases. The rest of the machinery in
            --  Valid_Conversion still ensures the proper compatibility of
            --  target and operand types.

           and then not In_Instance_Code
         then
            Conversion_Error_N (Msg, Operand);
         end if;

         return Valid;
      end Conversion_Check;

      ------------------------
      -- Conversion_Error_N --
      ------------------------

      procedure Conversion_Error_N (Msg : String; N : Node_Or_Entity_Id) is
      begin
         if Report_Errs then
            Error_Msg_N (Msg, N);
         end if;
      end Conversion_Error_N;

      -------------------------
      -- Conversion_Error_NE --
      -------------------------

      procedure Conversion_Error_NE
        (Msg : String;
         N   : Node_Or_Entity_Id;
         E   : Node_Or_Entity_Id)
      is
      begin
         if Report_Errs then
            Error_Msg_NE (Msg, N, E);
         end if;
      end Conversion_Error_NE;

      ----------------------
      -- In_Instance_Code --
      ----------------------

      function In_Instance_Code return Boolean is
         Par : Node_Id;

      begin
         if not In_Instance then
            return False;

         else
            Par := Parent (N);
            while Present (Par) loop

               --  The expression is part of an actual object if it appears in
               --  the generated object declaration in the instance.

               if Nkind (Par) = N_Object_Declaration
                 and then Present (Corresponding_Generic_Association (Par))
               then
                  return False;

               else
                  exit when
                    Nkind (Par) in N_Statement_Other_Than_Procedure_Call
                      or else Nkind (Par) in N_Subprogram_Call
                      or else Nkind (Par) in N_Declaration;
               end if;

               Par := Parent (Par);
            end loop;

            --  Otherwise the expression appears within the instantiated unit

            return True;
         end if;
      end In_Instance_Code;

      ----------------------------
      -- Valid_Array_Conversion --
      ----------------------------

      function Valid_Array_Conversion return Boolean is
         Opnd_Comp_Type : constant Entity_Id := Component_Type (Opnd_Type);
         Opnd_Comp_Base : constant Entity_Id := Base_Type (Opnd_Comp_Type);

         Opnd_Index      : Node_Id;
         Opnd_Index_Type : Entity_Id;

         Target_Comp_Type : constant Entity_Id :=
                              Component_Type (Target_Type);
         Target_Comp_Base : constant Entity_Id :=
                              Base_Type (Target_Comp_Type);

         Target_Index      : Node_Id;
         Target_Index_Type : Entity_Id;

      begin
         --  Error if wrong number of dimensions

         if
           Number_Dimensions (Target_Type) /= Number_Dimensions (Opnd_Type)
         then
            Conversion_Error_N
              ("incompatible number of dimensions for conversion", Operand);
            return False;

         --  Number of dimensions matches

         else
            --  Loop through indexes of the two arrays

            Target_Index := First_Index (Target_Type);
            Opnd_Index   := First_Index (Opnd_Type);
            while Present (Target_Index) and then Present (Opnd_Index) loop
               Target_Index_Type := Etype (Target_Index);
               Opnd_Index_Type   := Etype (Opnd_Index);

               --  Error if index types are incompatible

               if not (Is_Integer_Type (Target_Index_Type)
                       and then Is_Integer_Type (Opnd_Index_Type))
                 and then (Root_Type (Target_Index_Type)
                           /= Root_Type (Opnd_Index_Type))
               then
                  Conversion_Error_N
                    ("incompatible index types for array conversion",
                     Operand);
                  return False;
               end if;

               Next_Index (Target_Index);
               Next_Index (Opnd_Index);
            end loop;

            --  If component types have same base type, all set

            if Target_Comp_Base  = Opnd_Comp_Base then
               null;

               --  Here if base types of components are not the same. The only
               --  time this is allowed is if we have anonymous access types.

               --  The conversion of arrays of anonymous access types can lead
               --  to dangling pointers. AI-392 formalizes the accessibility
               --  checks that must be applied to such conversions to prevent
               --  out-of-scope references.

            elsif Ekind_In
                    (Target_Comp_Base, E_Anonymous_Access_Type,
                                       E_Anonymous_Access_Subprogram_Type)
              and then Ekind (Opnd_Comp_Base) = Ekind (Target_Comp_Base)
              and then
                Subtypes_Statically_Match (Target_Comp_Type, Opnd_Comp_Type)
            then
               if Type_Access_Level (Target_Type) <
                    Deepest_Type_Access_Level (Opnd_Type)
               then
                  if In_Instance_Body then
                     Error_Msg_Warn := SPARK_Mode /= On;
                     Conversion_Error_N
                       ("source array type has deeper accessibility "
                        & "level than target<<", Operand);
                     Conversion_Error_N ("\Program_Error [<<", Operand);
                     Rewrite (N,
                       Make_Raise_Program_Error (Sloc (N),
                         Reason => PE_Accessibility_Check_Failed));
                     Set_Etype (N, Target_Type);
                     return False;

                  --  Conversion not allowed because of accessibility levels

                  else
                     Conversion_Error_N
                       ("source array type has deeper accessibility "
                        & "level than target", Operand);
                     return False;
                  end if;

               else
                  null;
               end if;

            --  All other cases where component base types do not match

            else
               Conversion_Error_N
                 ("incompatible component types for array conversion",
                  Operand);
               return False;
            end if;

            --  Check that component subtypes statically match. For numeric
            --  types this means that both must be either constrained or
            --  unconstrained. For enumeration types the bounds must match.
            --  All of this is checked in Subtypes_Statically_Match.

            if not Subtypes_Statically_Match
                     (Target_Comp_Type, Opnd_Comp_Type)
            then
               Conversion_Error_N
                 ("component subtypes must statically match", Operand);
               return False;
            end if;
         end if;

         return True;
      end Valid_Array_Conversion;

      -----------------------------
      -- Valid_Tagged_Conversion --
      -----------------------------

      function Valid_Tagged_Conversion
        (Target_Type : Entity_Id;
         Opnd_Type   : Entity_Id) return Boolean
      is
      begin
         --  Upward conversions are allowed (RM 4.6(22))

         if Covers (Target_Type, Opnd_Type)
           or else Is_Ancestor (Target_Type, Opnd_Type)
         then
            return True;

         --  Downward conversion are allowed if the operand is class-wide
         --  (RM 4.6(23)).

         elsif Is_Class_Wide_Type (Opnd_Type)
           and then Covers (Opnd_Type, Target_Type)
         then
            return True;

         elsif Covers (Opnd_Type, Target_Type)
           or else Is_Ancestor (Opnd_Type, Target_Type)
         then
            return
              Conversion_Check (False,
                "downward conversion of tagged objects not allowed");

         --  Ada 2005 (AI-251): The conversion to/from interface types is
         --  always valid. The types involved may be class-wide (sub)types.

         elsif Is_Interface (Etype (Base_Type (Target_Type)))
           or else Is_Interface (Etype (Base_Type (Opnd_Type)))
         then
            return True;

         --  If the operand is a class-wide type obtained through a limited_
         --  with clause, and the context includes the nonlimited view, use
         --  it to determine whether the conversion is legal.

         elsif Is_Class_Wide_Type (Opnd_Type)
           and then From_Limited_With (Opnd_Type)
           and then Present (Non_Limited_View (Etype (Opnd_Type)))
           and then Is_Interface (Non_Limited_View (Etype (Opnd_Type)))
         then
            return True;

         elsif Is_Access_Type (Opnd_Type)
           and then Is_Interface (Directly_Designated_Type (Opnd_Type))
         then
            return True;

         else
            Conversion_Error_NE
              ("invalid tagged conversion, not compatible with}",
               N, First_Subtype (Opnd_Type));
            return False;
         end if;
      end Valid_Tagged_Conversion;

   --  Start of processing for Valid_Conversion

   begin
      Check_Parameterless_Call (Operand);

      if Is_Overloaded (Operand) then
         declare
            I   : Interp_Index;
            I1  : Interp_Index;
            It  : Interp;
            It1 : Interp;
            N1  : Entity_Id;
            T1  : Entity_Id;

         begin
            --  Remove procedure calls, which syntactically cannot appear in
            --  this context, but which cannot be removed by type checking,
            --  because the context does not impose a type.

            --  The node may be labelled overloaded, but still contain only one
            --  interpretation because others were discarded earlier. If this
            --  is the case, retain the single interpretation if legal.

            Get_First_Interp (Operand, I, It);
            Opnd_Type := It.Typ;
            Get_Next_Interp (I, It);

            if Present (It.Typ)
              and then Opnd_Type /= Standard_Void_Type
            then
               --  More than one candidate interpretation is available

               Get_First_Interp (Operand, I, It);
               while Present (It.Typ) loop
                  if It.Typ = Standard_Void_Type then
                     Remove_Interp (I);
                  end if;

                  --  When compiling for a system where Address is of a visible
                  --  integer type, spurious ambiguities can be produced when
                  --  arithmetic operations have a literal operand and return
                  --  System.Address or a descendant of it. These ambiguities
                  --  are usually resolved by the context, but for conversions
                  --  there is no context type and the removal of the spurious
                  --  operations must be done explicitly here.

                  if not Address_Is_Private
                    and then Is_Descendant_Of_Address (It.Typ)
                  then
                     Remove_Interp (I);
                  end if;

                  Get_Next_Interp (I, It);
               end loop;
            end if;

            Get_First_Interp (Operand, I, It);
            I1  := I;
            It1 := It;

            if No (It.Typ) then
               Conversion_Error_N ("illegal operand in conversion", Operand);
               return False;
            end if;

            Get_Next_Interp (I, It);

            if Present (It.Typ) then
               N1  := It1.Nam;
               T1  := It1.Typ;
               It1 := Disambiguate (Operand, I1, I, Any_Type);

               if It1 = No_Interp then
                  Conversion_Error_N
                    ("ambiguous operand in conversion", Operand);

                  --  If the interpretation involves a standard operator, use
                  --  the location of the type, which may be user-defined.

                  if Sloc (It.Nam) = Standard_Location then
                     Error_Msg_Sloc := Sloc (It.Typ);
                  else
                     Error_Msg_Sloc := Sloc (It.Nam);
                  end if;

                  Conversion_Error_N -- CODEFIX
                    ("\\possible interpretation#!", Operand);

                  if Sloc (N1) = Standard_Location then
                     Error_Msg_Sloc := Sloc (T1);
                  else
                     Error_Msg_Sloc := Sloc (N1);
                  end if;

                  Conversion_Error_N -- CODEFIX
                    ("\\possible interpretation#!", Operand);

                  return False;
               end if;
            end if;

            Set_Etype (Operand, It1.Typ);
            Opnd_Type := It1.Typ;
         end;
      end if;

      --  Deal with conversion of integer type to address if the pragma
      --  Allow_Integer_Address is in effect. We convert the conversion to
      --  an unchecked conversion in this case and we are all done.

      if Address_Integer_Convert_OK (Opnd_Type, Target_Type) then
         Rewrite (N, Unchecked_Convert_To (Target_Type, Expression (N)));
         Analyze_And_Resolve (N, Target_Type);
         return True;
      end if;

      --  If we are within a child unit, check whether the type of the
      --  expression has an ancestor in a parent unit, in which case it
      --  belongs to its derivation class even if the ancestor is private.
      --  See RM 7.3.1 (5.2/3).

      Inc_Ancestor := Get_Incomplete_View_Of_Ancestor (Opnd_Type);

      --  Numeric types

      if Is_Numeric_Type (Target_Type) then

         --  A universal fixed expression can be converted to any numeric type

         if Opnd_Type = Universal_Fixed then
            return True;

         --  Also no need to check when in an instance or inlined body, because
         --  the legality has been established when the template was analyzed.
         --  Furthermore, numeric conversions may occur where only a private
         --  view of the operand type is visible at the instantiation point.
         --  This results in a spurious error if we check that the operand type
         --  is a numeric type.

         --  Note: in a previous version of this unit, the following tests were
         --  applied only for generated code (Comes_From_Source set to False),
         --  but in fact the test is required for source code as well, since
         --  this situation can arise in source code.

         elsif In_Instance_Code or else In_Inlined_Body then
            return True;

         --  Otherwise we need the conversion check

         else
            return Conversion_Check
                     (Is_Numeric_Type (Opnd_Type)
                       or else
                         (Present (Inc_Ancestor)
                           and then Is_Numeric_Type (Inc_Ancestor)),
                      "illegal operand for numeric conversion");
         end if;

      --  Array types

      elsif Is_Array_Type (Target_Type) then
         if not Is_Array_Type (Opnd_Type)
           or else Opnd_Type = Any_Composite
           or else Opnd_Type = Any_String
         then
            Conversion_Error_N
              ("illegal operand for array conversion", Operand);
            return False;

         else
            return Valid_Array_Conversion;
         end if;

      --  Ada 2005 (AI-251): Internally generated conversions of access to
      --  interface types added to force the displacement of the pointer to
      --  reference the corresponding dispatch table.

      elsif not Comes_From_Source (N)
         and then Is_Access_Type (Target_Type)
         and then Is_Interface (Designated_Type (Target_Type))
      then
         return True;

      --  Ada 2005 (AI-251): Anonymous access types where target references an
      --  interface type.

      elsif Is_Access_Type (Opnd_Type)
        and then Ekind_In (Target_Type, E_General_Access_Type,
                                        E_Anonymous_Access_Type)
        and then Is_Interface (Directly_Designated_Type (Target_Type))
      then
         --  Check the static accessibility rule of 4.6(17). Note that the
         --  check is not enforced when within an instance body, since the
         --  RM requires such cases to be caught at run time.

         --  If the operand is a rewriting of an allocator no check is needed
         --  because there are no accessibility issues.

         if Nkind (Original_Node (N)) = N_Allocator then
            null;

         elsif Ekind (Target_Type) /= E_Anonymous_Access_Type then
            if Type_Access_Level (Opnd_Type) >
               Deepest_Type_Access_Level (Target_Type)
            then
               --  In an instance, this is a run-time check, but one we know
               --  will fail, so generate an appropriate warning. The raise
               --  will be generated by Expand_N_Type_Conversion.

               if In_Instance_Body then
                  Error_Msg_Warn := SPARK_Mode /= On;
                  Conversion_Error_N
                    ("cannot convert local pointer to non-local access type<<",
                     Operand);
                  Conversion_Error_N ("\Program_Error [<<", Operand);

               else
                  Conversion_Error_N
                    ("cannot convert local pointer to non-local access type",
                     Operand);
                  return False;
               end if;

            --  Special accessibility checks are needed in the case of access
            --  discriminants declared for a limited type.

            elsif Ekind (Opnd_Type) = E_Anonymous_Access_Type
              and then not Is_Local_Anonymous_Access (Opnd_Type)
            then
               --  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 (Object_Access_Level handles
               --  checking the prefix of the operand for this case).

               if Nkind (Operand) = N_Selected_Component
                 and then Object_Access_Level (Operand) >
                   Deepest_Type_Access_Level (Target_Type)
               then
                  --  In an instance, this is a run-time check, but one we know
                  --  will fail, so generate an appropriate warning. The raise
                  --  will be generated by Expand_N_Type_Conversion.

                  if In_Instance_Body then
                     Error_Msg_Warn := SPARK_Mode /= On;
                     Conversion_Error_N
                       ("cannot convert access discriminant to non-local "
                        & "access type<<", Operand);
                     Conversion_Error_N ("\Program_Error [<<", Operand);

                  --  Real error if not in instance body

                  else
                     Conversion_Error_N
                       ("cannot convert access discriminant to non-local "
                        & "access type", Operand);
                     return False;
                  end if;
               end if;

               --  The case of a reference to an access discriminant from
               --  within a limited type declaration (which will appear as
               --  a discriminal) is always illegal because the level of the
               --  discriminant is considered to be deeper than any (nameable)
               --  access type.

               if Is_Entity_Name (Operand)
                 and then not Is_Local_Anonymous_Access (Opnd_Type)
                 and then
                   Ekind_In (Entity (Operand), E_In_Parameter, E_Constant)
                 and then Present (Discriminal_Link (Entity (Operand)))
               then
                  Conversion_Error_N
                    ("discriminant has deeper accessibility level than target",
                     Operand);
                  return False;
               end if;
            end if;
         end if;

         return True;

      --  General and anonymous access types

      elsif Ekind_In (Target_Type, E_General_Access_Type,
                                   E_Anonymous_Access_Type)
          and then
            Conversion_Check
              (Is_Access_Type (Opnd_Type)
                and then not
                  Ekind_In (Opnd_Type, E_Access_Subprogram_Type,
                                       E_Access_Protected_Subprogram_Type),
               "must be an access-to-object type")
      then
         if Is_Access_Constant (Opnd_Type)
           and then not Is_Access_Constant (Target_Type)
         then
            Conversion_Error_N
              ("access-to-constant operand type not allowed", Operand);
            return False;
         end if;

         --  Check the static accessibility rule of 4.6(17). Note that the
         --  check is not enforced when within an instance body, since the RM
         --  requires such cases to be caught at run time.

         if Ekind (Target_Type) /= E_Anonymous_Access_Type
           or else Is_Local_Anonymous_Access (Target_Type)
           or else Nkind (Associated_Node_For_Itype (Target_Type)) =
                     N_Object_Declaration
         then
            --  Ada 2012 (AI05-0149): Perform legality checking on implicit
            --  conversions from an anonymous access type to a named general
            --  access type. Such conversions are not allowed in the case of
            --  access parameters and stand-alone objects of an anonymous
            --  access type. The implicit conversion case is recognized by
            --  testing that Comes_From_Source is False and that it's been
            --  rewritten. The Comes_From_Source test isn't sufficient because
            --  nodes in inlined calls to predefined library routines can have
            --  Comes_From_Source set to False. (Is there a better way to test
            --  for implicit conversions???)

            if Ada_Version >= Ada_2012
              and then not Comes_From_Source (N)
              and then Is_Rewrite_Substitution (N)
              and then Ekind (Base_Type (Target_Type)) = E_General_Access_Type
              and then Ekind (Opnd_Type) = E_Anonymous_Access_Type
            then
               if Is_Itype (Opnd_Type) then

                  --  Implicit conversions aren't allowed for objects of an
                  --  anonymous access type, since such objects have nonstatic
                  --  levels in Ada 2012.

                  if Nkind (Associated_Node_For_Itype (Opnd_Type)) =
                       N_Object_Declaration
                  then
                     Conversion_Error_N
                       ("implicit conversion of stand-alone anonymous "
                        & "access object not allowed", Operand);
                     return False;

                  --  Implicit conversions aren't allowed for anonymous access
                  --  parameters. The "not Is_Local_Anonymous_Access_Type" test
                  --  is done to exclude anonymous access results.

                  elsif not Is_Local_Anonymous_Access (Opnd_Type)
                    and then Nkind_In (Associated_Node_For_Itype (Opnd_Type),
                                       N_Function_Specification,
                                       N_Procedure_Specification)
                  then
                     Conversion_Error_N
                       ("implicit conversion of anonymous access formal "
                        & "not allowed", Operand);
                     return False;

                  --  This is a case where there's an enclosing object whose
                  --  to which the "statically deeper than" relationship does
                  --  not apply (such as an access discriminant selected from
                  --  a dereference of an access parameter).

                  elsif Object_Access_Level (Operand)
                          = Scope_Depth (Standard_Standard)
                  then
                     Conversion_Error_N
                       ("implicit conversion of anonymous access value "
                        & "not allowed", Operand);
                     return False;

                  --  In other cases, the level of the operand's type must be
                  --  statically less deep than that of the target type, else
                  --  implicit conversion is disallowed (by RM12-8.6(27.1/3)).

                  elsif Type_Access_Level (Opnd_Type) >
                        Deepest_Type_Access_Level (Target_Type)
                  then
                     Conversion_Error_N
                       ("implicit conversion of anonymous access value "
                        & "violates accessibility", Operand);
                     return False;
                  end if;
               end if;

            elsif Type_Access_Level (Opnd_Type) >
                    Deepest_Type_Access_Level (Target_Type)
            then
               --  In an instance, this is a run-time check, but one we know
               --  will fail, so generate an appropriate warning. The raise
               --  will be generated by Expand_N_Type_Conversion.

               if In_Instance_Body then
                  Error_Msg_Warn := SPARK_Mode /= On;
                  Conversion_Error_N
                    ("cannot convert local pointer to non-local access type<<",
                     Operand);
                  Conversion_Error_N ("\Program_Error [<<", Operand);

               --  If not in an instance body, this is a real error

               else
                  --  Avoid generation of spurious error message

                  if not Error_Posted (N) then
                     Conversion_Error_N
                      ("cannot convert local pointer to non-local access type",
                       Operand);
                  end if;

                  return False;
               end if;

            --  Special accessibility checks are needed in the case of access
            --  discriminants declared for a limited type.

            elsif Ekind (Opnd_Type) = E_Anonymous_Access_Type
              and then not Is_Local_Anonymous_Access (Opnd_Type)
            then
               --  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 (Object_Access_Level handles
               --  checking the prefix of the operand for this case).

               if Nkind (Operand) = N_Selected_Component
                 and then Object_Access_Level (Operand) >
                          Deepest_Type_Access_Level (Target_Type)
               then
                  --  In an instance, this is a run-time check, but one we know
                  --  will fail, so generate an appropriate warning. The raise
                  --  will be generated by Expand_N_Type_Conversion.

                  if In_Instance_Body then
                     Error_Msg_Warn := SPARK_Mode /= On;
                     Conversion_Error_N
                       ("cannot convert access discriminant to non-local "
                        & "access type<<", Operand);
                     Conversion_Error_N ("\Program_Error [<<", Operand);

                  --  If not in an instance body, this is a real error

                  else
                     Conversion_Error_N
                       ("cannot convert access discriminant to non-local "
                        & "access type", Operand);
                     return False;
                  end if;
               end if;

               --  The case of a reference to an access discriminant from
               --  within a limited type declaration (which will appear as
               --  a discriminal) is always illegal because the level of the
               --  discriminant is considered to be deeper than any (nameable)
               --  access type.

               if Is_Entity_Name (Operand)
                 and then
                   Ekind_In (Entity (Operand), E_In_Parameter, E_Constant)
                 and then Present (Discriminal_Link (Entity (Operand)))
               then
                  Conversion_Error_N
                    ("discriminant has deeper accessibility level than target",
                     Operand);
                  return False;
               end if;
            end if;
         end if;

         --  In the presence of limited_with clauses we have to use nonlimited
         --  views, if available.

         Check_Limited : declare
            function Full_Designated_Type (T : Entity_Id) return Entity_Id;
            --  Helper function to handle limited views

            --------------------------
            -- Full_Designated_Type --
            --------------------------

            function Full_Designated_Type (T : Entity_Id) return Entity_Id is
               Desig : constant Entity_Id := Designated_Type (T);

            begin
               --  Handle the limited view of a type

               if From_Limited_With (Desig)
                 and then Has_Non_Limited_View (Desig)
               then
                  return Available_View (Desig);
               else
                  return Desig;
               end if;
            end Full_Designated_Type;

            --  Local Declarations

            Target : constant Entity_Id := Full_Designated_Type (Target_Type);
            Opnd   : constant Entity_Id := Full_Designated_Type (Opnd_Type);

            Same_Base : constant Boolean :=
                          Base_Type (Target) = Base_Type (Opnd);

         --  Start of processing for Check_Limited

         begin
            if Is_Tagged_Type (Target) then
               return Valid_Tagged_Conversion (Target, Opnd);

            else
               if not Same_Base then
                  Conversion_Error_NE
                    ("target designated type not compatible with }",
                     N, Base_Type (Opnd));
                  return False;

               --  Ada 2005 AI-384: legality rule is symmetric in both
               --  designated types. The conversion is legal (with possible
               --  constraint check) if either designated type is
               --  unconstrained.

               elsif Subtypes_Statically_Match (Target, Opnd)
                 or else
                   (Has_Discriminants (Target)
                     and then
                      (not Is_Constrained (Opnd)
                        or else not Is_Constrained (Target)))
               then
                  --  Special case, if Value_Size has been used to make the
                  --  sizes different, the conversion is not allowed even
                  --  though the subtypes statically match.

                  if Known_Static_RM_Size (Target)
                    and then Known_Static_RM_Size (Opnd)
                    and then RM_Size (Target) /= RM_Size (Opnd)
                  then
                     Conversion_Error_NE
                       ("target designated subtype not compatible with }",
                        N, Opnd);
                     Conversion_Error_NE
                       ("\because sizes of the two designated subtypes differ",
                        N, Opnd);
                     return False;

                  --  Normal case where conversion is allowed

                  else
                     return True;
                  end if;

               else
                  Error_Msg_NE
                    ("target designated subtype not compatible with }",
                     N, Opnd);
                  return False;
               end if;
            end if;
         end Check_Limited;

      --  Access to subprogram types. If the operand is an access parameter,
      --  the type has a deeper accessibility that any master, and cannot be
      --  assigned. We must make an exception if the conversion is part of an
      --  assignment and the target is the return object of an extended return
      --  statement, because in that case the accessibility check takes place
      --  after the return.

      elsif Is_Access_Subprogram_Type (Target_Type)

        --  Note: this test of Opnd_Type is there to prevent entering this
        --  branch in the case of a remote access to subprogram type, which
        --  is internally represented as an E_Record_Type.

        and then Is_Access_Type (Opnd_Type)
      then
         if Ekind (Base_Type (Opnd_Type)) = E_Anonymous_Access_Subprogram_Type
           and then Is_Entity_Name (Operand)
           and then Ekind (Entity (Operand)) = E_In_Parameter
           and then
             (Nkind (Parent (N)) /= N_Assignment_Statement
               or else not Is_Entity_Name (Name (Parent (N)))
               or else not Is_Return_Object (Entity (Name (Parent (N)))))
         then
            Conversion_Error_N
              ("illegal attempt to store anonymous access to subprogram",
               Operand);
            Conversion_Error_N
              ("\value has deeper accessibility than any master "
               & "(RM 3.10.2 (13))",
               Operand);

            Error_Msg_NE
             ("\use named access type for& instead of access parameter",
               Operand, Entity (Operand));
         end if;

         --  Check that the designated types are subtype conformant

         Check_Subtype_Conformant (New_Id  => Designated_Type (Target_Type),
                                   Old_Id  => Designated_Type (Opnd_Type),
                                   Err_Loc => N);

         --  Check the static accessibility rule of 4.6(20)

         if Type_Access_Level (Opnd_Type) >
            Deepest_Type_Access_Level (Target_Type)
         then
            Conversion_Error_N
              ("operand type has deeper accessibility level than target",
               Operand);

         --  Check that if the operand type is declared in a generic body,
         --  then the target type must be declared within that same body
         --  (enforces last sentence of 4.6(20)).

         elsif Present (Enclosing_Generic_Body (Opnd_Type)) then
            declare
               O_Gen : constant Node_Id :=
                         Enclosing_Generic_Body (Opnd_Type);

               T_Gen : Node_Id;

            begin
               T_Gen := Enclosing_Generic_Body (Target_Type);
               while Present (T_Gen) and then T_Gen /= O_Gen loop
                  T_Gen := Enclosing_Generic_Body (T_Gen);
               end loop;

               if T_Gen /= O_Gen then
                  Conversion_Error_N
                    ("target type must be declared in same generic body "
                     & "as operand type", N);
               end if;
            end;
         end if;

         return True;

      --  Remote access to subprogram types

      elsif Is_Remote_Access_To_Subprogram_Type (Target_Type)
        and then Is_Remote_Access_To_Subprogram_Type (Opnd_Type)
      then
         --  It is valid to convert from one RAS type to another provided
         --  that their specification statically match.

         --  Note: at this point, remote access to subprogram types have been
         --  expanded to their E_Record_Type representation, and we need to
         --  go back to the original access type definition using the
         --  Corresponding_Remote_Type attribute in order to check that the
         --  designated profiles match.

         pragma Assert (Ekind (Target_Type) = E_Record_Type);
         pragma Assert (Ekind (Opnd_Type) = E_Record_Type);

         Check_Subtype_Conformant
           (New_Id  =>
              Designated_Type (Corresponding_Remote_Type (Target_Type)),
            Old_Id  =>
              Designated_Type (Corresponding_Remote_Type (Opnd_Type)),
            Err_Loc =>
              N);
         return True;

      --  If it was legal in the generic, it's legal in the instance

      elsif In_Instance_Body then
         return True;

      --  If both are tagged types, check legality of view conversions

      elsif Is_Tagged_Type (Target_Type)
              and then
            Is_Tagged_Type (Opnd_Type)
      then
         return Valid_Tagged_Conversion (Target_Type, Opnd_Type);

      --  Types derived from the same root type are convertible

      elsif Root_Type (Target_Type) = Root_Type (Opnd_Type) then
         return True;

      --  In an instance or an inlined body, there may be inconsistent views of
      --  the same type, or of types derived from a common root.

      elsif (In_Instance or In_Inlined_Body)
        and then
          Root_Type (Underlying_Type (Target_Type)) =
          Root_Type (Underlying_Type (Opnd_Type))
      then
         return True;

      --  Special check for common access type error case

      elsif Ekind (Target_Type) = E_Access_Type
         and then Is_Access_Type (Opnd_Type)
      then
         Conversion_Error_N ("target type must be general access type!", N);
         Conversion_Error_NE -- CODEFIX
            ("add ALL to }!", N, Target_Type);
         return False;

      --  Here we have a real conversion error

      else
         --  Check for missing regular with_clause when only a limited view of
         --  target is available.

         if From_Limited_With (Opnd_Type) and then In_Package_Body then
            Conversion_Error_NE
              ("invalid conversion, not compatible with limited view of }",
               N, Opnd_Type);
            Conversion_Error_NE
              ("\add with_clause for& to current unit!", N, Scope (Opnd_Type));

         elsif Is_Access_Type (Opnd_Type)
           and then From_Limited_With (Designated_Type (Opnd_Type))
           and then In_Package_Body
         then
            Conversion_Error_NE
              ("invalid conversion, not compatible with }", N, Opnd_Type);
            Conversion_Error_NE
              ("\add with_clause for& to current unit!",
               N, Scope (Designated_Type (Opnd_Type)));

         else
            Conversion_Error_NE
              ("invalid conversion, not compatible with }", N, Opnd_Type);
         end if;

         return False;
      end if;
   end Valid_Conversion;

end Sem_Res;
