------------------------------------------------------------------------------
--                                                                          --
--                         GNAT COMPILER COMPONENTS                         --
--                                                                          --
--                              S E M _ R E S                               --
--                                                                          --
--                                 B o d y                                  --
--                                                                          --
--          Copyright (C) 1992-2021, Free Software Foundation, Inc.         --
--                                                                          --
-- GNAT is free software;  you can  redistribute it  and/or modify it under --
-- terms of the  GNU General Public License as published  by the Free Soft- --
-- ware  Foundation;  either version 3,  or (at your option) any later ver- --
-- sion.  GNAT is distributed in the hope that it will be useful, but WITH- --
-- OUT ANY WARRANTY;  without even the  implied warranty of MERCHANTABILITY --
-- or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License --
-- for  more details.  You should have  received  a copy of the GNU General --
-- Public License  distributed with GNAT; see file COPYING3.  If not, go to --
-- http://www.gnu.org/licenses for a complete copy of the license.          --
--                                                                          --
-- GNAT was originally developed  by the GNAT team at  New York University. --
-- Extensive contributions were provided by Ada Core Technologies Inc.      --
--                                                                          --
------------------------------------------------------------------------------

with Aspects;        use Aspects;
with Atree;          use Atree;
with Checks;         use Checks;
with Debug;          use Debug;
with Debug_A;        use Debug_A;
with Einfo;          use Einfo;
with Einfo.Entities; use Einfo.Entities;
with Einfo.Utils;    use Einfo.Utils;
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.Nodes;    use Sinfo.Nodes;
with Sinfo.Utils;    use Sinfo.Utils;
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_Declare_Expression        (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_Implicit_Dereference (P : Node_Id);
   --  Called when P is the prefix of an indexed component, or of a selected
   --  component, or of a slice. If P is of an access type, we unconditionally
   --  rewrite it as an explicit dereference. This ensures that the expander
   --  and the code generator have a fully explicit tree to work with.

   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. This rewrites the conversion into a simpler form.

   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 (Parent (Parent (P))) in 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 (PN) in 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 Nkind (P) not in
           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 (Parent (P)) in 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 (N) in 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 (Parent (HSS)) in 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 Attribute_Name (Parent (N))
                       in 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 (Parent (N)) in 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 (Entity (Selector_Name (N))) in
                          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
         Set_Etype (N, Empty);
         Set_Entity (N, Empty);
         Set_Is_Overloaded (N, False);
         Change_Operator_Symbol_To_String_Literal (N);
         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 Op_Name in Name_Op_Multiply | Name_Op_Divide
           and then Is_Fixed_Point_Type (Etype (Act1))
           and then Is_Fixed_Point_Type (Etype (Act2))
         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 Op_Name in Name_Op_Eq | Name_Op_Ne
           and then (Is_Anonymous_Access_Type (Etype (Act1))
                      or else Is_Anonymous_Access_Type (Etype (Act2)))
         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 Op_Name in 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 Op_Name in 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;
   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));

            --  Examine possible interpretations, and adapt the message
            --  for inherited subprograms declared by a type derivation.

            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;

         --  Additional message and hint if the ambiguity involves an Ada2020
         --  container aggregate.

         Check_Ambiguous_Aggregate (N);
      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;

      Literal_Aspect_Map :
        constant array (N_Numeric_Or_String_Literal) of Aspect_Id :=
          (N_Integer_Literal => Aspect_Integer_Literal,
           N_Real_Literal    => Aspect_Real_Literal,
           N_String_Literal  => Aspect_String_Literal);

      Named_Number_Aspect_Map : constant array (Named_Kind) of Aspect_Id :=
        (E_Named_Integer => Aspect_Integer_Literal,
         E_Named_Real    => Aspect_Real_Literal);

   --  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 Attribute_Name (N) in 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, but if the node comes from source it is a
      --  Declare_Expression and requires scope management.

      if Nkind (N) = N_Expression_With_Actions then
         if Comes_From_Source (N) and then N = Original_Node (N) then
            Resolve_Declare_Expression (N, Typ);
         else
            Resolve (Expression (N), Typ);
         end if;

         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 not Is_Universal_Numeric_Type (Typ)
                 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 (N) in 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 (N) in 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
               if Ada_Version >= Ada_2020
                 and then Has_Aspect (Typ, Aspect_Aggregate)
               then
                  Resolve_Container_Aggregate (N, Typ);

                  if Expander_Active then
                     Expand (N);
                  end if;
                  return;
               end if;

               --  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;

            --  Rewrite Literal as a call if the corresponding literal aspect
            --  is set.

            if (Nkind (N) in N_Numeric_Or_String_Literal
                 and then
                   Present
                     (Find_Aspect (Typ, Literal_Aspect_Map (Nkind (N)))))
              or else
                (Nkind (N) = N_Identifier
                  and then Is_Named_Number (Entity (N))
                  and then
                    Present
                      (Find_Aspect
                        (Typ, Named_Number_Aspect_Map (Ekind (Entity (N))))))
            then
               declare
                  Lit_Aspect : constant Aspect_Id :=
                    (if Nkind (N) = N_Identifier
                     then Named_Number_Aspect_Map (Ekind (Entity (N)))
                     else Literal_Aspect_Map (Nkind (N)));

                  Loc  : constant Source_Ptr := Sloc (N);

                  Callee : Entity_Id :=
                    Entity (Expression (Find_Aspect (Typ, Lit_Aspect)));

                  Name : constant Node_Id :=
                    Make_Identifier (Loc, Chars (Callee));

                  Param1 : Node_Id;
                  Param2 : Node_Id;
                  Params : List_Id;
                  Call   : Node_Id;
                  Expr   : Node_Id;

               begin
                  if Nkind (N) = N_Identifier then
                     Expr := Expression (Declaration_Node (Entity (N)));

                     if Ekind (Entity (N)) = E_Named_Integer then
                        UI_Image (Expr_Value (Expr), Decimal);
                        Start_String;
                        Store_String_Chars
                          (UI_Image_Buffer (1 .. UI_Image_Length));
                        Param1 := Make_String_Literal (Loc, End_String);
                        Params := New_List (Param1);

                     else
                        UI_Image (Norm_Num (Expr_Value_R (Expr)), Decimal);
                        Start_String;
                        Store_String_Chars
                          (UI_Image_Buffer (1 .. UI_Image_Length));
                        Param1 := Make_String_Literal (Loc, End_String);

                        --  Note: Set_Etype is called below on Param1

                        UI_Image (Norm_Den (Expr_Value_R (Expr)), Decimal);
                        Start_String;
                        Store_String_Chars
                          (UI_Image_Buffer (1 .. UI_Image_Length));
                        Param2 := Make_String_Literal (Loc, End_String);
                        Set_Etype (Param2, Standard_String);

                        Params := New_List (Param1, Param2);

                        if Present (Related_Expression (Callee)) then
                           Callee := Related_Expression (Callee);
                        else
                           Error_Msg_NE
                             ("cannot resolve & for a named real", N, Callee);
                           return;
                        end if;
                     end if;

                  elsif Nkind (N) = N_String_Literal then
                     Param1 := Make_String_Literal (Loc, Strval (N));
                     Params := New_List (Param1);
                  else
                     Param1 :=
                       Make_String_Literal
                         (Loc, String_From_Numeric_Literal (N));
                     Params := New_List (Param1);
                  end if;

                  Call :=
                    Make_Function_Call
                      (Sloc                   => Loc,
                       Name                   => Name,
                       Parameter_Associations => Params);

                  Set_Entity (Name, Callee);
                  Set_Is_Overloaded (Name, False);

                  if Lit_Aspect = Aspect_String_Literal then
                     Set_Etype (Param1, Standard_Wide_Wide_String);
                  else
                     Set_Etype (Param1, Standard_String);
                  end if;

                  Set_Etype (Call, Etype (Callee));

                  --  Conversion needed in case of an inherited aspect
                  --  of a derived type.
                  --
                  --  ??? Need to do something different here for downward
                  --  tagged conversion case (which is only possible in the
                  --  case of a null extension); the current call to
                  --  Convert_To results in an error message about an illegal
                  --  downward conversion.

                  Call := Convert_To (Typ, Call);

                  Rewrite (N, Call);
               end;

               Analyze_And_Resolve (N, Typ);
               return;
            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.Null_Address.

            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 interpretation

      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 for reading in interfering context (SPARK RM 7.1.3(10)).

      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 Object_Type_Has_Constrained_Partial_View
                                (Typ => F_Typ, Scop => Current_Scope)
               then
                  null;

               else
                  Error_Msg_NE ("untagged actual does not statically 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)))
                            < Static_Accessibility_Level (A, Object_Decl_Level)
               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))))
                         < Static_Accessibility_Level (A, Object_Decl_Level)
            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 for reading and if it does, emit an error.

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

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

         begin
            case Nkind (N) is

               --  Do not consider object name appearing in the prefix of
               --  attribute Address as a read.

               when N_Attribute_Reference =>

                  --  Prefix of attribute Address denotes an object, program
                  --  unit, or label; none of them needs to be flagged here.

                  if Attribute_Name (N) = Name_Address then
                     return Skip;
                  end if;

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

               when N_Function_Call =>
                  return Skip;

               when N_Identifier | N_Expanded_Name =>
                  Id := Entity (N);

                  if Present (Id)
                    and then Is_Object (Id)
                    and then Is_Effectively_Volatile_For_Reading (Id)
                  then
                     Error_Msg_N
                       ("volatile object cannot appear in this context"
                        & " (SPARK RM 7.1.3(10))", N);
                  end if;

                  return Skip;

               when others =>
                  null;
            end case;

            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
               declare
                  Expr_Typ : constant Entity_Id := Etype (Expression (A));

               begin
                  --  Check RM 4.6 (24.2/2)

                  if Is_Array_Type (Etype (F))
                    and then Is_View_Conversion (A)
                  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)).

                     --  Check RM 4.6 (24.8/2)

                     if Has_Aliased_Components (Expr_Typ) /=
                        Has_Aliased_Components (Etype (F))
                     then
                        --  This normally illegal conversion is legal in an
                        --  expanded instance body because of RM 12.3(11).
                        --  At runtime, conversion must create a new object.

                        if not In_Instance then
                           Error_Msg_N
                             ("both component types in a view conversion must"
                              & " be aliased, or neither", A);
                        end if;

                     --  Check RM 4.6 (24/3)

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

                        if Is_By_Reference_Type (Etype (F))
                          or else Is_By_Reference_Type (Expr_Typ)
                        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 (Expr_Typ);
                           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;

                  --  AI12-0074 & AI12-0377
                  --  Check 6.4.1: If the mode is out, the actual parameter is
                  --  a view conversion, and the type of the formal parameter
                  --  is a scalar type, then either:
                  --    - the target and operand type both do not have the
                  --      Default_Value aspect specified; or
                  --    - the target and operand type both have the
                  --      Default_Value aspect specified, and there shall exist
                  --      a type (other than a root numeric type) that is an
                  --      ancestor of both the target type and the operand
                  --      type.

                  elsif Ekind (F) = E_Out_Parameter
                    and then Is_Scalar_Type (Etype (F))
                  then
                     if Has_Default_Aspect (Etype (F)) /=
                        Has_Default_Aspect (Expr_Typ)
                     then
                        Error_Msg_N
                          ("view conversion requires Default_Value on both " &
                           "types (RM 6.4.1)", A);
                     elsif Has_Default_Aspect (Expr_Typ)
                       and then not Same_Ancestor (Etype (F), Expr_Typ)
                     then
                        Error_Msg_N
                          ("view conversion between unrelated types with "
                           & "Default_Value not allowed (RM 6.4.1)", A);
                     end if;
                  end if;
               end;

               --  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;

            --  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 (F) in 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 (F) in 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 Ekind (Nam) = E_Procedure
                       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/VFA actual (RM C.6(12))

            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_Ref (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);

               elsif Is_Volatile_Full_Access_Object_Ref (A)
                 and then not Is_Volatile_Full_Access (Etype (F))
               then
                  Error_Msg_NE
                    ("cannot pass full access object to nonfull access "
                     & "formal&", A, F);
                  Error_Msg_N
                    ("\which is passed by reference (RM C.6(12))", A);
               end if;

               --  Check for nonatomic subcomponent of a full access object
               --  in Ada 2020 (RM C.6 (12)).

               if Ada_Version >= Ada_2020
                 and then Is_Subcomponent_Of_Full_Access_Object (A)
                 and then not Is_Atomic_Object (A)
               then
                  Error_Msg_N
                    ("cannot pass nonatomic subcomponent of full access "
                     & "object", A);
                  Error_Msg_NE
                    ("\to formal & which is passed by reference (RM C.6(12))",
                     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 for reading may act as an
               --  actual when the corresponding formal is of a non-scalar
               --  effectively volatile type for reading (SPARK RM 7.1.3(10)).

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

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

               elsif Is_Unchecked_Conversion_Instance (Nam) then
                  null;

               --  The actual denotes an object

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

               --  Otherwise the actual denotes an expression. Inspect the
               --  expression and flag each effectively volatile object
               --  for reading 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 for reading 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_For_Reading (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 (F) in 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;

            --  (AI12-0397): The target of a subprogram call that occurs within
            --  the expression of an Default_Initial_Condition aspect and has
            --  an actual that is the current instance of the type must be
            --  either a primitive of the type or a class-wide subprogram,
            --  because the type of the current instance in such an aspect is
            --  considered to be a notional formal derived type whose only
            --  operations correspond to the primitives of the enclosing type.
            --  Nonprimitives can be called, but the current instance must be
            --  converted rather than passed directly. Note that a current
            --  instance of a type with DIC will occur as a reference to an
            --  in-mode formal of an enclosing DIC procedure or partial DIC
            --  procedure. (It seems that this check should perhaps also apply
            --  to calls within Type_Invariant'Class, but not Type_Invariant,
            --  aspects???)

            if Nkind (A) = N_Identifier
              and then Ekind (Entity (A)) = E_In_Parameter

              and then Is_Subprogram (Scope (Entity (A)))
              and then Is_DIC_Procedure (Scope (Entity (A)))

              --  We check Comes_From_Source to exclude inherited primitives
              --  from being flagged, because such subprograms turn out to not
              --  always have the Is_Primitive flag set. ???

              and then Comes_From_Source (Nam)

              and then not Is_Primitive (Nam)
              and then not Is_Class_Wide_Type (Etype (F))
            then
               Error_Msg_NE
                 ("call to nonprimitive & with current instance not allowed " &
                  "for aspect", A, Nam);
            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 Static_Accessibility_Level
                      (Disc_Exp, Zero_On_Dynamic_Level)
                        > 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 Static_Accessibility_Level
                      (Disc_Exp, Zero_On_Dynamic_Level)
                        > 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);
               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;

         --  Do a full resolution to apply constraint and predicate checks

         Resolve_Qualified_Expression (E, Etype (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;

         --  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 (Aggr) in 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 or within a formal package. A run-time check will be
               --  performed in the instance.

               elsif not Is_Generic_Type (Exp_Typ)
                 and then not In_Generic_Formal_Package (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 (Parent (N)) in 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 Is_Universal_Numeric_Type (T);
         else
            Get_First_Interp (N, Index, It);
            while Present (It.Typ) loop
               if Base_Type (It.Typ) = Base_Type (Standard_Integer)
                 or else Is_Universal_Numeric_Type (It.Typ)
               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 Is_Universal_Numeric_Type (T))
         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 (Parent (N)) in 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 (N) in 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 Is_Universal_Numeric_Type (Etype (N)) 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 Is_Universal_Numeric_Type (B_Typ)
        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 (N) in 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 Nkind (Parent (N)) not in
                         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 Nkind (Parent (N)) not in
                            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 Is_Universal_Numeric_Type (TL)
               and then
            Is_Universal_Numeric_Type (TR)
         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);

      --  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 (N) in 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 (N) in 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
      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;

   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 (Subp) in N_Selected_Component | N_Indexed_Component
        or else (Is_Entity_Name (Subp) and then Is_Entry (Entity (Subp)))
      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;

      --  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;

      --  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);

                  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));

                  Resolve_Indexed_Component (N, Typ);
               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;

         --  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 not Is_Static_Function (Scop)
           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

                  --  Ada 202x (AI12-0075): Static functions are never allowed
                  --  to make a recursive call, as specified by 6.8(5.4/5).

                  if Is_Static_Function (Scop) then
                     Error_Msg_N
                       ("recursive call not allowed in static expression "
                          & "function", N);

                     Set_Error_Posted (Scop);

                     exit Scope_Loop;
                  end if;

                  --  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 Nkind (P) not in 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.

      --  g) If the subprogram is a static expression function and the call is
      --  a static call (the actuals are all static expressions), then we never
      --  want to create a transient scope (this could occur in the case of a
      --  static string-returning call).

      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)
        or else Is_Static_Function_Call (N)
      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 (Nam) in 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 (F) in 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);

      --  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);

      --  Ada 202x (AI12-0075): If the call is a static call to a static
      --  expression function, then we want to "inline" the call, replacing
      --  it with the folded static result. This is not done if the checking
      --  for a potentially static expression is enabled or if an error has
      --  been posted on the call (which may be due to the check for recursive
      --  calls, in which case we don't want to fall into infinite recursion
      --  when doing the inlining).

      if not Checking_Potentially_Static_Expression
        and then Is_Static_Function_Call (N)
        and then not Is_Intrinsic_Subprogram (Ultimate_Alias (Nam))
        and then not Error_Posted (Ultimate_Alias (Nam))
      then
         Inline_Static_Function_Call (N, Ultimate_Alias (Nam));

      --  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.

      elsif 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
               Cannot_Inline
                 ("cannot inline & (in assertion expression)?", N, Nam_UA,
                  Suppress_Info => No (Body_Id));

            --  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);

      --  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);

      Eval_Relational_Op (N);
   end Resolve_Comparison_Op;

   --------------------------------
   -- Resolve_Declare_Expression --
   --------------------------------

   procedure Resolve_Declare_Expression
     (N   : Node_Id;
      Typ : Entity_Id)
   is
      Decl                 : Node_Id;
      Need_Transient_Scope : Boolean := False;
   begin
      --  Install the scope created for local declarations, if
      --  any. The syntax allows a Declare_Expression with no
      --  declarations, in analogy with block statements.
      --  Note that that scope has no explicit declaration, but
      --  appears as the scope of all entities declared therein.

      Decl := First (Actions (N));
      while Present (Decl) loop
         exit when Nkind (Decl)
                     in N_Object_Declaration | N_Object_Renaming_Declaration;
         Next (Decl);
      end loop;

      if Present (Decl) then

         --  Need to establish a transient scope in case Expression (N)
         --  requires actions to be wrapped.

         declare
            Node : Node_Id;
         begin
            Node := First (Actions (N));
            while Present (Node) loop
               if Nkind (Node) = N_Object_Declaration
                 and then Is_Type (Etype (Defining_Identifier (Node)))
                 and then Requires_Transient_Scope
                            (Etype (Defining_Identifier (Node)))
               then
                  Need_Transient_Scope := True;
                  exit;
               end if;

               Next (Node);
            end loop;
         end;

         if Need_Transient_Scope then
            Establish_Transient_Scope (Decl, True);
         else
            Push_Scope (Scope (Defining_Identifier (Decl)));
         end if;

         declare
            E : Entity_Id := First_Entity (Current_Scope);
         begin
            while Present (E) loop
               Set_Current_Entity (E);
               Set_Is_Immediately_Visible (E);
               Next_Entity (E);
            end loop;
         end;

         Resolve (Expression (N), Typ);
         End_Scope;

      else
         Resolve (Expression (N), Typ);
      end if;
   end Resolve_Declare_Expression;

   -----------------------------------------
   -- 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.

      function Is_Attribute_Expression (Expr : Node_Id) return Boolean;
      --  Determine whether Expr is part of an N_Attribute_Reference
      --  expression.

      ----------------------------------------
      -- Is_Assignment_Or_Object_Expression --
      ----------------------------------------

      function Is_Assignment_Or_Object_Expression
        (Context : Node_Id;
         Expr    : Node_Id) return Boolean
      is
      begin
         if Nkind (Context) in
              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 (Context) in N_Attribute_Reference
                                 | N_Explicit_Dereference
                                 | N_Indexed_Component
                                 | N_Selected_Component
                                 | N_Slice
                  and then Prefix (Context) = Expr)
           or else
               (Nkind (Context) in 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;

      -----------------------------
      -- Is_Attribute_Expression --
      -----------------------------

      function Is_Attribute_Expression (Expr : Node_Id) return Boolean is
         N : Node_Id := Expr;
      begin
         while Present (N) loop
            if Nkind (N) = N_Attribute_Reference then
               return True;
            end if;

            N := Parent (N);
         end loop;

         return False;
      end Is_Attribute_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 (Is_Scalar_Type (Etype (E))
                   or else not Is_Attribute_Expression (Parent (N)))

        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 for reading must appear in
            --  non-interfering context (SPARK RM 7.1.3(10)).

            if Is_Object (E)
              and then Is_Effectively_Volatile_For_Reading (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(10))", 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_Check 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));
         Resolve_Implicit_Dereference (Prefix (Entry_Name));

      else pragma Assert (Nkind (Entry_Name) = N_Indexed_Component);
         Nam := Entity (Selector_Name (Prefix (Entry_Name)));
         Resolve (Prefix (Prefix (Entry_Name)));
         Resolve_Implicit_Dereference (Prefix (Prefix (Entry_Name)));

         --  We do not resolve the prefix because an Entry_Family has no type,
         --  although it has the semantics of an array since it can be indexed.
         --  In order to perform the associated range check, we would need to
         --  build an array type on the fly and set it on the prefix, but this
         --  would be wasteful since only the index type matters. Therefore we
         --  attach this index type directly, so that Actual_Index_Expression
         --  can pick it up later in order to generate the range check.

         Set_Etype (Prefix (Entry_Name), Actual_Index_Type (Nam));

         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_Scalar_Range_Check (Index, Etype (Prefix (Entry_Name)));
         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 Is_Entry (Nam)
        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 Is_Entry (Nam) 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;

      --  Now we know that this is not a call to a function that returns an
      --  array type; moreover, we know the name of the called entry. Detect
      --  overlapping actuals, just like for a subprogram call.

      Warn_On_Overlapping_Actuals (Nam, N);

   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.

      function Suspicious_Prio_For_Equality return Boolean;
      --  Returns True iff the parent node is a and/or/xor operation that
      --  could be the cause of confused priorities. Note that if the not is
      --  in parens, then False is returned.

      -------------------------
      -- 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 (Etype (R)) in E_Allocator_Type | E_Access_Attribute_Type
         then
            Acc := Designated_Type (Etype (R));

         elsif Ekind (Etype (L)) in 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;

      ----------------------------------
      -- Suspicious_Prio_For_Equality --
      ----------------------------------

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

      begin
         --  Check if parent node is one of and/or/xor, not parenthesized
         --  explicitly, and its own parent is not of this kind. Otherwise,
         --  it's a case of chained Boolean conditions which is likely well
         --  parenthesized.

         if Nkind (Par) in N_Op_And | N_Op_Or | N_Op_Xor
           and then Paren_Count (N) = 0
           and then Nkind (Parent (Par)) not in N_Op_And | N_Op_Or | N_Op_Xor
         then
            declare
               Compar : Node_Id :=
                 (if Left_Opnd (Par) = N then
                     Right_Opnd (Par)
                  else
                     Left_Opnd (Par));
            begin
               --  Compar may have been rewritten, for example from (a /= b)
               --  into not (a = b). Use the Original_Node instead.

               Compar := Original_Node (Compar);

               --  If the other argument of the and/or/xor is also a
               --  comparison, or another and/or/xor then most likely
               --  the priorities are correctly set.

               return Nkind (Compar) not in N_Op_Boolean;
            end;

         else
            return False;
         end if;
      end Suspicious_Prio_For_Equality;

   --  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 (T) in 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 Is_Anonymous_Access_Type (Etype (L))
           and then Is_Anonymous_Access_Type (Etype (R))
         then
            Check_If_Expression (L);
            Check_If_Expression (R);
         end if;

         Resolve (L, T);
         Resolve (R, T);

         --  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;

         --  Warn on a (in)equality between boolean values which is not
         --  parenthesized when the parent expression is one of and/or/xor, as
         --  this is interpreted as (a = b) op c where most likely a = (b op c)
         --  was intended. Do not generate a warning in generic instances, as
         --  the problematic expression may be implicitly parenthesized in
         --  the generic itself if one of the operators is a generic formal.
         --  Also do not generate a warning for generated equality, for
         --  example from rewritting a membership test.

         if Warn_On_Questionable_Missing_Parens
           and then not In_Instance
           and then Comes_From_Source (N)
           and then Is_Boolean_Type (T)
           and then Suspicious_Prio_For_Equality
         then
            Error_Msg_N ("?q?equality should be parenthesized here!", N);
         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 (T) in 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_Packed_Array (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

      function OK_For_Static (Act : Node_Id) return Boolean;
      --  True if Act is an action of a declare_expression that is allowed in a
      --  static declare_expression.

      function All_OK_For_Static return Boolean;
      --  True if all actions of N are allowed in a static declare_expression.

      function Get_Literal (Expr : Node_Id) return Node_Id;
      --  Expr is an expression with compile-time-known value. This returns the
      --  literal node that reprsents that value.

      function OK_For_Static (Act : Node_Id) return Boolean is
      begin
         case Nkind (Act) is
            when N_Object_Declaration =>
               if Constant_Present (Act)
                 and then Is_Static_Expression (Expression (Act))
               then
                  return True;
               end if;

            when N_Object_Renaming_Declaration =>
               if Statically_Names_Object (Name (Act)) then
                  return True;
               end if;

            when others =>
               --  No other declarations, nor even pragmas, are allowed in a
               --  declare expression, so if we see something else, it must be
               --  an internally generated expression_with_actions.
               null;
         end case;

         return False;
      end OK_For_Static;

      function All_OK_For_Static return Boolean is
         Act : Node_Id := First (Actions (N));
      begin
         while Present (Act) loop
            if not OK_For_Static (Act) then
               return False;
            end if;

            Next (Act);
         end loop;

         return True;
      end All_OK_For_Static;

      function Get_Literal (Expr : Node_Id) return Node_Id is
         pragma Assert (Compile_Time_Known_Value (Expr));
         Result : Node_Id;
      begin
         case Nkind (Expr) is
            when N_Has_Entity =>
               if Ekind (Entity (Expr)) = E_Enumeration_Literal then
                  Result := Expr;
               else
                  Result := Constant_Value (Entity (Expr));
               end if;
            when N_Numeric_Or_String_Literal =>
               Result := Expr;
            when others =>
               raise Program_Error;
         end case;

         pragma Assert
           (Nkind (Result) in N_Numeric_Or_String_Literal
              or else Ekind (Entity (Result)) = E_Enumeration_Literal);
         return Result;
      end Get_Literal;

      Loc : constant Source_Ptr := Sloc (N);

   begin
      Set_Etype (N, Typ);

      if Is_Empty_List (Actions (N)) then
         pragma Assert (All_OK_For_Static); null;
      end if;

      --  If the value of the expression is known at compile time, and all
      --  of the actions (if any) are suitable, then replace the declare
      --  expression with its expression. This allows the declare expression
      --  as a whole to be static if appropriate. See AI12-0368.

      if Compile_Time_Known_Value (Expression (N)) then
         if Is_Empty_List (Actions (N)) then
            Rewrite (N, Expression (N));
         elsif All_OK_For_Static then
            Rewrite
              (N, New_Copy_Tree
                    (Get_Literal (Expression (N)), New_Sloc => Loc));
         end if;
      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);
   begin
      Rewrite (N, Indexing);
      Resolve (N, Typ);
   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.

      Result_Type  : Entity_Id := Typ;
      --  So in most cases the type of the If_Expression and of its
      --  dependent expressions is that of the context. However, if
      --  the expression is the index of an Indexed_Component, we must
      --  ensure that a proper index check is applied, rather than a
      --  range check on the index type (which might be discriminant
      --  dependent). In this case we resolve with the base type of the
      --  index type, and the index check is generated in the resolution
      --  of the indexed_component above.

      -----------------
      -- 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 (Result_Type, Loc),
                Expression   => Relocate_Node (Expr)));

            Analyze_And_Resolve (Expr, Result_Type);
         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;

      if Nkind (Parent (N)) = N_Indexed_Component
        or else Nkind (Parent (Parent (N))) = N_Indexed_Component
      then
         Result_Type := Base_Type (Typ);
      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, Result_Type);
      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, Result_Type);
         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, Result_Type);
         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, Result_Type);

      if not Error_Posted (N) then
         Eval_If_Expression (N);
      end if;

      Analyze_Dimension (N);
   end Resolve_If_Expression;

   ----------------------------------
   -- Resolve_Implicit_Dereference --
   ----------------------------------

   procedure Resolve_Implicit_Dereference (P : Node_Id) is
      Desig_Typ : Entity_Id;

   begin
      --  In an instance the proper view may not always be correct for
      --  private types, see e.g. Sem_Type.Covers for similar handling.

      if Is_Private_Type (Etype (P))
        and then Present (Full_View (Etype (P)))
        and then Is_Access_Type (Full_View (Etype (P)))
        and then In_Instance
      then
         Set_Etype (P, Full_View (Etype (P)));
      end if;

      if Is_Access_Type (Etype (P)) then
         Desig_Typ := Implicitly_Designated_Type (Etype (P));
         Insert_Explicit_Dereference (P);
         Analyze_And_Resolve (P, Desig_Typ);
      end if;
   end Resolve_Implicit_Dereference;

   -------------------------------
   -- 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 the prefix's type is an access type, get to the real array type.
      --  Note: we do not apply an access check because an explicit dereference
      --  will be introduced later, and the check will happen there.

      if Is_Access_Type (Array_Type) then
         Array_Type := Implicitly_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 then Present (Expr) loop
            Resolve (Expr, Etype (Index));
            Check_Unset_Reference (Expr);

            Apply_Scalar_Range_Check (Expr, Etype (Index));

            Next_Index (Index);
            Next (Expr);
         end loop;
      end if;

      Resolve_Implicit_Dereference (Prefix (N));
      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, then this is
      --  worth a warning before Ada 2020, since we have a situation where the
      --  access to the component may cause extra read/writes of the atomic
      --  object, or partial word accesses, both of which may 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))
        and then Ada_Version < Ada_2020
      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 (Opnd) in 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 (N) in 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);
   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 Assert (Is_Boolean_Type (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 as
      --  the basis to resolve the disjuncts.

      ----------------------------
      -- Resolve_Set_Membership --
      ----------------------------

      procedure Resolve_Set_Membership is
         Alt  : Node_Id;

      begin
         --  If the left operand is overloaded, find type compatible with not
         --  overloaded alternative of the right operand.

         Alt := First (Alternatives (N));
         if Is_Overloaded (L) then
            T := Empty;
            while Present (Alt) loop
               if not Is_Overloaded (Alt) then
                  T := 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 (T) then
               Error_Msg_N ("ambiguous expression", N);
            end if;

         else
            T := Intersect_Types (L, Alt);
         end if;

         Resolve (L, T);

         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, T);
            end if;

            Next (Alt);
         end loop;

         --  Check for duplicates for discrete case

         if Is_Discrete_Type (T) 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 (Alt) in N_Integer_Literal
                                          | N_Character_Literal
                                          | 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;

                  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 (Etype (L))
           and then Present (Get_User_Defined_Eq (Etype (L)))
         then
            Error_Msg_NE
              ("membership test on& uses predefined equality?", N, Etype (L));
            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 Is_Universal_Numeric_Type (Etype (R))
        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;
   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;

      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 Is_Universal_Numeric_Type (Etype (Left_Opnd (N))) 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
      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
         return Paren_Count (N) = 0
           and then Nkind (Parent (N)) in N_Membership_Test
                                        | N_Op_Boolean
                                        | N_Short_Circuit
            and then Left_Opnd (Parent (N)) = N;
      end Parent_Is_Boolean;

      --  Local variables

      B_Typ : Entity_Id;

   --  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 (Opnd) in 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);

      --  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. But we avoid doing it
      --  for an allocator since this is not needed and might be problematic.

      if Is_Composite_Type (Target_Typ)
        and then not Is_Constrained (Target_Typ)
        and then Nkind (Parent (N)) /= N_Allocator
      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 (Target_Typ)
      then
         Apply_Scalar_Range_Check (Expr, Target_Typ);
      end if;

      --  AI12-0100: Once the qualified expression is resolved, check whether
      --  operand statisfies a static predicate of the target subtype, if any.
      --  In the static expression case, a predicate check failure is an error.

      if Has_Predicates (Target_Typ) then
         Check_Expression_Against_Static_Predicate
           (Expr, Target_Typ, Static_Failure_Is_Error => True);
      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
               return Is_Entity_Name (PL)
                 and then Is_Entity_Name (PH)
                 and then Entity (PL) = Entity (PH);
            end;
         end if;

         return False;
      end First_Last_Ref;

   --  Start of processing for Resolve_Range

   begin
      Set_Etype (N, Typ);

      Resolve (L, Typ);
      Resolve (H, 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), Static => True);
         end if;

         if Is_OK_Static_Expression (H) then
            Fold_Uint (H, Expr_Value (H), Static => True);
         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
                                 Next_Entity (Comp1);
                              end loop;
                           end if;

                           exit Search;
                        end if;
                     end if;
                  end if;

                  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 the prefix's type is an access type, get to the real record type.
      --  Note: we do not apply an access check because an explicit dereference
      --  will be introduced later, and the check will happen there.

      if Is_Access_Type (Etype (P)) then
         T := Implicitly_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;

      --  Eval_Selected_Component may e.g. fold statically known discriminants.

      Eval_Selected_Component (N);

      if Nkind (N) = N_Selected_Component then

         --  If the record type is atomic and the component is not, then this
         --  is worth a warning before Ada 2020, since we have a situation
         --  where the access to the component may cause extra read/writes of
         --  the atomic object, or partial word accesses, both of which may be
         --  unexpected.

         if Is_Atomic_Ref_With_Address (N)
           and then not Is_Atomic (Entity (S))
           and then not Is_Atomic (Etype (Entity (S)))
           and then Ada_Version < Ada_2020
         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;

         Resolve_Implicit_Dereference (Prefix (N));
         Analyze_Dimension (N);
      end if;
   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.

            Preserve_Comes_From_Source (L, 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 the prefix's type is an access type, get to the real array type.
      --  Note: we do not apply an access check because an explicit dereference
      --  will be introduced later, and the check will happen there.

      if Is_Access_Type (Array_Type) then
         Array_Type := Implicitly_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;

      Resolve_Implicit_Dereference (Prefix (N));
      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 Nkind (Original_Node (N)) not in 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 : Int;

            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 := 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 (Operand) in 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 (Operand) in 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);

      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. But skip them if
      --  universal fixed operands are involved, since range checks are handled
      --  separately for these cases, after the expansion done by 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 Etype (Operand) /= 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 Present (Entity (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 (Parent (N)) in 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.

            else
               if Is_Entity_Name (Orig_N) then
                  Error_Msg_Node_2 := Orig_T;
                  Error_Msg_NE -- CODEFIX
                    ("?r?redundant conversion, & is of type &!",
                     N, Entity (Orig_N));
               else
                  Error_Msg_NE
                    ("?r?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 (Opnd) in 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 a static predicate of the target subtype, if any.
      --  In the static expression case, a predicate check failure is an error.

      if Has_Predicates (Target_Typ) then
         Check_Expression_Against_Static_Predicate
           (N, Target_Typ, Static_Failure_Is_Error => True);
      end if;

      --  If at this stage we have a fixed to integer conversion, make sure the
      --  Do_Range_Check flag is set, because such conversions in general need
      --  a range check. We only need this if expansion is off, see above why.

      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)
        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
      --  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 Is_Universal_Numeric_Type (Etype (R)) then
         Check_For_Visible_Operator (N, B_Typ);
      end if;

      Set_Etype (N, B_Typ);
      Resolve (R, B_Typ);

      --  Generate warning for negative literal of a modular type, unless it is
      --  enclosed directly in a type qualification or a type conversion, as it
      --  is likely not what the user intended. We don't issue the warning for
      --  the common use of -1 to denote OxFFFF_FFFF...

      if Warn_On_Suspicious_Modulus_Value
        and then Nkind (N) = N_Op_Minus
        and then Nkind (R) = N_Integer_Literal
        and then Is_Modular_Integer_Type (B_Typ)
        and then Nkind (Parent (N)) not in N_Qualified_Expression
                                         | N_Type_Conversion
        and then Expr_Value (R) > Uint_1
      then
         Error_Msg_N
           ("?M?negative literal of modular type is in fact positive", N);
         Error_Msg_Uint_1 := (-Expr_Value (R)) mod Modulus (B_Typ);
         Error_Msg_Uint_2 := Expr_Value (R);
         Error_Msg_N ("\do you really mean^ when writing -^ '?", N);
         Error_Msg_N
           ("\if you do, use qualification to avoid this warning", N);
      end if;

      --  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 (Rorig) in 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 (Rorig) in 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);

      --  If the expression is a conversion to universal integer of an
      --  an expression with an integer type, then we can eliminate the
      --  intermediate conversion to universal integer.

      if Nkind (Operand) = N_Type_Conversion
        and then Entity (Subtype_Mark (Operand)) = Universal_Integer
        and then Is_Integer_Type (Etype (Expression (Operand)))
      then
         Rewrite (Operand, Relocate_Node (Expression (Operand)));
         Analyze_And_Resolve (Operand);
      end if;

      --  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, or in GNATprove mode to
      --  capture the associated run-time exceptions if any.

      elsif Expander_Active or GNATprove_Mode 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.
      --  If the length is 1, then the upper bound is set to a mere copy of
      --  the lower bound; or else, if the index type is a signed integer,
      --  then the upper bound is computed as Low_Bound + L - 1; otherwise,
      --  the upper bound is computed as T'Val (T'Pos (Low_Bound) + L - 1).

      else
         declare
            Length        : constant Nat := String_Length (Strval (N));
            Index_List    : constant List_Id   := New_List;
            Index_Type    : constant Entity_Id := Etype (First_Index (Typ));
            Array_Subtype : Entity_Id;
            Drange        : Node_Id;
            High_Bound    : Node_Id;
            Index         : Node_Id;
            Index_Subtype : Entity_Id;

         begin
            if Length = 1 then
               High_Bound := New_Copy_Tree (Low_Bound);

            elsif Is_Signed_Integer_Type (Index_Type) then
               High_Bound :=
                 Make_Op_Add (Loc,
                   Left_Opnd  => New_Copy_Tree (Low_Bound),
                   Right_Opnd => Make_Integer_Literal (Loc, Length - 1));

            else
               High_Bound :=
                 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, Length - 1))));
            end if;

            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)));
            end if;

            Analyze_And_Resolve
              (String_Literal_Low_Bound (Subtype_Id), Base_Type (Index_Type));

            --  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 Attribute_Name (Operand) in 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;

            --  Special processing for the conversion of an integer literal to
            --  a dynamic type: we first convert the literal to the root type
            --  and then convert the result to the target type, the goal being
            --  to avoid doing range checks in universal integer.

            elsif Is_Integer_Type (Target_Typ)
              and then not Is_Generic_Type (Root_Type (Target_Typ))
              and then Nkind (Operand) = N_Integer_Literal
              and then Opnd_Typ = Universal_Integer
            then
               Convert_To_And_Rewrite (Root_Type (Target_Typ), Operand);
               Analyze_And_Resolve (Operand);

            --  If the expression is a conversion to universal integer of an
            --  an expression with an integer type, then we can eliminate the
            --  intermediate conversion to universal integer.

            elsif Nkind (Operand) = N_Type_Conversion
              and then Entity (Subtype_Mark (Operand)) = Universal_Integer
              and then Is_Integer_Type (Etype (Expression (Operand)))
            then
               Rewrite (Operand, Relocate_Node (Expression (Operand)));
               Analyze_And_Resolve (Operand);
            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 (N) in 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 Is_Discrim_Of_Bad_Access_Conversion_Argument
        (Expr : Node_Id) return Boolean;
      --  Implicit anonymous-to-named access type conversions are not allowed
      --  if the "statically deeper than" relationship does not apply to the
      --  type of the conversion operand. See RM 8.6(28.1) and AARM 8.6(28.d).
      --  We deal with most such cases elsewhere so that we can emit more
      --  specific error messages (e.g., if the operand is an access parameter
      --  or a saooaaat (stand-alone object of an anonymous access type)), but
      --  here is where we catch the case where the operand is an access
      --  discriminant selected from a dereference of another such "bad"
      --  conversion argument.

      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;

      --------------------------------------------------
      -- Is_Discrim_Of_Bad_Access_Conversion_Argument --
      --------------------------------------------------

      function Is_Discrim_Of_Bad_Access_Conversion_Argument
        (Expr : Node_Id) return Boolean
      is
         Exp_Type : Entity_Id := Base_Type (Etype (Expr));
         pragma Assert (Is_Access_Type (Exp_Type));

         Associated_Node : Node_Id;
         Deref_Prefix : Node_Id;
      begin
         if not Is_Anonymous_Access_Type (Exp_Type) then
            return False;
         end if;

         pragma Assert (Is_Itype (Exp_Type));
         Associated_Node := Associated_Node_For_Itype (Exp_Type);

         if Nkind (Associated_Node) /= N_Discriminant_Specification then
            return False; -- not the type of an access discriminant
         end if;

         --  return False if Expr not of form <prefix>.all.Some_Component

         if (Nkind (Expr) /= N_Selected_Component)
           or else (Nkind (Prefix (Expr)) /= N_Explicit_Dereference)
         then
            --  conditional expressions, declare expressions ???
            return False;
         end if;

         Deref_Prefix := Prefix (Prefix (Expr));
         Exp_Type := Base_Type (Etype (Deref_Prefix));

         --  The "statically deeper relationship" does not apply
         --  to generic formal access types, so a prefix of such
         --  a type is a "bad" prefix.

         if Is_Generic_Formal (Exp_Type) then
            return True;

         --  The "statically deeper relationship" does apply to
         --  any other named access type.

         elsif not Is_Anonymous_Access_Type (Exp_Type) then
            return False;
         end if;

         pragma Assert (Is_Itype (Exp_Type));
         Associated_Node := Associated_Node_For_Itype (Exp_Type);

         --  The "statically deeper relationship" applies to some
         --  anonymous access types and not to others. Return
         --  True for the cases where it does not apply. Also check
         --  recursively for the
         --     <prefix>.all.Access_Discrim.all.Access_Discrim case,
         --  where the correct result depends on <prefix>.

         return Nkind (Associated_Node) in
                  N_Procedure_Specification |  -- access parameter
                  N_Function_Specification  |  -- access parameter
                  N_Object_Declaration         -- saooaaat
           or else Is_Discrim_Of_Bad_Access_Conversion_Argument (Deref_Prefix);
      end Is_Discrim_Of_Bad_Access_Conversion_Argument;

      ----------------------------
      -- 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 (Target_Comp_Base) in
                    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 (Target_Type) in
                   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 (Accessibility_Level handles
               --  checking the prefix of the operand for this case).

               if Nkind (Operand) = N_Selected_Component
                 and then Static_Accessibility_Level
                            (Operand, Zero_On_Dynamic_Level)
                              > 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 (Entity (Operand)) in 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 (Target_Type) in
              E_General_Access_Type | E_Anonymous_Access_Type
          and then
            Conversion_Check
              (Is_Access_Type (Opnd_Type)
                and then
                  Ekind (Opnd_Type) not in
                    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???).
            --
            --  Do not treat a rewritten 'Old attribute reference like other
            --  rewrite substitutions. This makes a difference, for example,
            --  in the case where we are generating the expansion of a
            --  membership test of the form
            --     Saooaaat'Old in Named_Access_Type
            --  because in this case Valid_Conversion needs to return True
            --  (otherwise the expansion will be False - see the call site
            --  in exp_ch4.adb).

            if Ada_Version >= Ada_2012
              and then not Comes_From_Source (N)
              and then Is_Rewrite_Substitution (N)
              and then not Is_Attribute_Old (Original_Node (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. We exclude anonymous access results as well
                  --  as universal_access "=".

                  elsif not Is_Local_Anonymous_Access (Opnd_Type)
                    and then Nkind (Associated_Node_For_Itype (Opnd_Type)) in
                               N_Function_Specification |
                               N_Procedure_Specification
                    and then Nkind (Parent (N)) not in N_Op_Eq | N_Op_Ne
                  then
                     Conversion_Error_N
                       ("implicit conversion of anonymous access parameter "
                        & "not allowed", Operand);
                     return False;

                  --  Detect access discriminant values that are illegal
                  --  implicit anonymous-to-named access conversion operands.

                  elsif Is_Discrim_Of_Bad_Access_Conversion_Argument (Operand)
                  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;

            --  Check if the operand is deeper than the target type, taking
            --  care to avoid the case where we are converting a result of a
            --  function returning an anonymous access type since the "master
            --  of the call" would be target type of the conversion unless
            --  the target type is anonymous access as well - see RM 3.10.2
            --  (10.3/3).

            elsif Type_Access_Level (Opnd_Type) >
                    Deepest_Type_Access_Level (Target_Type)
              and then (Nkind (Associated_Node_For_Itype (Opnd_Type)) /=
                         N_Function_Specification
                        or else Ekind (Target_Type) in
                                  Anonymous_Access_Kind)

              --  Check we are not in a return value ???

              and then (not In_Return_Value (N)
                         or else
                           Nkind (Associated_Node_For_Itype (Target_Type))
                             = N_Component_Declaration)
            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 (Accessibility_Level handles
               --  checking the prefix of the operand for this case).

               if Nkind (Operand) = N_Selected_Component
                 and then Static_Accessibility_Level
                            (Operand, Zero_On_Dynamic_Level)
                              > 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 (Entity (Operand)) in 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;
