------------------------------------------------------------------------------
--                                                                          --
--                         GNAT COMPILER COMPONENTS                         --
--                                                                          --
--                              S E M _ C H 6                               --
--                                                                          --
--                                 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 Contracts;      use Contracts;
with Debug;          use Debug;
with Einfo;          use Einfo;
with Einfo.Entities; use Einfo.Entities;
with Einfo.Utils;    use Einfo.Utils;
with Elists;         use Elists;
with Errout;         use Errout;
with Expander;       use Expander;
with Exp_Ch3;        use Exp_Ch3;
with Exp_Ch6;        use Exp_Ch6;
with Exp_Ch7;        use Exp_Ch7;
with Exp_Ch9;        use Exp_Ch9;
with Exp_Dbug;       use Exp_Dbug;
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.Xref;       use Lib.Xref;
with Layout;         use Layout;
with Namet;          use Namet;
with Lib;            use Lib;
with Nlists;         use Nlists;
with Nmake;          use Nmake;
with Opt;            use Opt;
with Output;         use Output;
with Restrict;       use Restrict;
with Rtsfind;        use Rtsfind;
with Sem;            use Sem;
with Sem_Aux;        use Sem_Aux;
with Sem_Cat;        use Sem_Cat;
with Sem_Ch3;        use Sem_Ch3;
with Sem_Ch4;        use Sem_Ch4;
with Sem_Ch5;        use Sem_Ch5;
with Sem_Ch8;        use Sem_Ch8;
with Sem_Ch9;        use Sem_Ch9;
with Sem_Ch10;       use Sem_Ch10;
with Sem_Ch12;       use Sem_Ch12;
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_Elim;       use Sem_Elim;
with Sem_Eval;       use Sem_Eval;
with Sem_Mech;       use Sem_Mech;
with Sem_Prag;       use Sem_Prag;
with Sem_Res;        use Sem_Res;
with Sem_Util;       use Sem_Util;
with Sem_Type;       use Sem_Type;
with Sem_Warn;       use Sem_Warn;
with Sinput;         use Sinput;
with Stand;          use Stand;
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 Stringt;        use Stringt;
with Style;
with Stylesw;        use Stylesw;
with Tbuild;         use Tbuild;
with Uintp;          use Uintp;
with Urealp;         use Urealp;
with Validsw;        use Validsw;

package body Sem_Ch6 is

   May_Hide_Profile : Boolean := False;
   --  This flag is used to indicate that two formals in two subprograms being
   --  checked for conformance differ only in that one is an access parameter
   --  while the other is of a general access type with the same designated
   --  type. In this case, if the rest of the signatures match, a call to
   --  either subprogram may be ambiguous, which is worth a warning. The flag
   --  is set in Compatible_Types, and the warning emitted in
   --  New_Overloaded_Entity.

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

   procedure Analyze_Function_Return (N : Node_Id);
   --  Subsidiary to Analyze_Return_Statement. Called when the return statement
   --  applies to a [generic] function.

   procedure Analyze_Generic_Subprogram_Body (N : Node_Id; Gen_Id : Entity_Id);
   --  Analyze a generic subprogram body. N is the body to be analyzed, and
   --  Gen_Id is the defining entity Id for the corresponding spec.

   procedure Analyze_Null_Procedure
     (N             : Node_Id;
      Is_Completion : out Boolean);
   --  A null procedure can be a declaration or (Ada 2012) a completion

   procedure Analyze_Return_Statement (N : Node_Id);
   --  Common processing for simple and extended return statements

   procedure Analyze_Return_Type (N : Node_Id);
   --  Subsidiary to Process_Formals: analyze subtype mark in function
   --  specification in a context where the formals are visible and hide
   --  outer homographs.

   procedure Analyze_Subprogram_Body_Helper (N : Node_Id);
   --  Does all the real work of Analyze_Subprogram_Body. This is split out so
   --  that we can use RETURN but not skip the debug output at the end.

   function Can_Override_Operator (Subp : Entity_Id) return Boolean;
   --  Returns true if Subp can override a predefined operator.

   procedure Check_Conformance
     (New_Id                   : Entity_Id;
      Old_Id                   : Entity_Id;
      Ctype                    : Conformance_Type;
      Errmsg                   : Boolean;
      Conforms                 : out Boolean;
      Err_Loc                  : Node_Id := Empty;
      Get_Inst                 : Boolean := False;
      Skip_Controlling_Formals : Boolean := False);
   --  Given two entities, this procedure checks that the profiles associated
   --  with these entities meet the conformance criterion given by the third
   --  parameter. If they conform, Conforms is set True and control returns
   --  to the caller. If they do not conform, Conforms is set to False, and
   --  in addition, if Errmsg is True on the call, proper messages are output
   --  to complain about the conformance failure. If Err_Loc is non_Empty
   --  the error messages are placed on Err_Loc, if Err_Loc is empty, then
   --  error messages are placed on the appropriate part of the construct
   --  denoted by New_Id. If Get_Inst is true, then this is a mode conformance
   --  against a formal access-to-subprogram type so Get_Instance_Of must
   --  be called.

   procedure Check_Formal_Subprogram_Conformance
     (New_Id   : Entity_Id;
      Old_Id   : Entity_Id;
      Err_Loc  : Node_Id;
      Errmsg   : Boolean;
      Conforms : out Boolean);
   --  Core implementation of Check_Formal_Subprogram_Conformance from spec.
   --  Errmsg can be set to False to not emit error messages.
   --  Conforms is set to True if there is conformance, False otherwise.

   procedure Check_Limited_Return
     (N      : Node_Id;
      Expr   : Node_Id;
      R_Type : Entity_Id);
   --  Check the appropriate (Ada 95 or Ada 2005) rules for returning limited
   --  types. Used only for simple return statements. Expr is the expression
   --  returned.

   procedure Check_Subprogram_Order (N : Node_Id);
   --  N is the N_Subprogram_Body node for a subprogram. This routine applies
   --  the alpha ordering rule for N if this ordering requirement applicable.

   procedure Check_Returns
     (HSS  : Node_Id;
      Mode : Character;
      Err  : out Boolean;
      Proc : Entity_Id := Empty);
   --  Called to check for missing return statements in a function body, or for
   --  returns present in a procedure body which has No_Return set. HSS is the
   --  handled statement sequence for the subprogram body. This procedure
   --  checks all flow paths to make sure they either have return (Mode = 'F',
   --  used for functions) or do not have a return (Mode = 'P', used for
   --  No_Return procedures). The flag Err is set if there are any control
   --  paths not explicitly terminated by a return in the function case, and is
   --  True otherwise. Proc is the entity for the procedure case and is used
   --  in posting the warning message.

   procedure Check_Untagged_Equality (Eq_Op : Entity_Id);
   --  In Ada 2012, a primitive equality operator on an untagged record type
   --  must appear before the type is frozen, and have the same visibility as
   --  that of the type. This procedure checks that this rule is met, and
   --  otherwise emits an error on the subprogram declaration and a warning
   --  on the earlier freeze point if it is easy to locate. In Ada 2012 mode,
   --  this routine outputs errors (or warnings if -gnatd.E is set). In earlier
   --  versions of Ada, warnings are output if Warn_On_Ada_2012_Incompatibility
   --  is set, otherwise the call has no effect.

   procedure Enter_Overloaded_Entity (S : Entity_Id);
   --  This procedure makes S, a new overloaded entity, into the first visible
   --  entity with that name.

   function Is_Non_Overriding_Operation
     (Prev_E : Entity_Id;
      New_E  : Entity_Id) return Boolean;
   --  Enforce the rule given in 12.3(18): a private operation in an instance
   --  overrides an inherited operation only if the corresponding operation
   --  was overriding in the generic. This needs to be checked for primitive
   --  operations of types derived (in the generic unit) from formal private
   --  or formal derived types.

   procedure Make_Inequality_Operator (S : Entity_Id);
   --  Create the declaration for an inequality operator that is implicitly
   --  created by a user-defined equality operator that yields a boolean.

   procedure Preanalyze_Formal_Expression (N : Node_Id; T : Entity_Id);
   --  Preanalysis of default expressions of subprogram formals. N is the
   --  expression to be analyzed and T is the expected type.

   procedure Set_Formal_Validity (Formal_Id : Entity_Id);
   --  Formal_Id is an formal parameter entity. This procedure deals with
   --  setting the proper validity status for this entity, which depends on
   --  the kind of parameter and the validity checking mode.

   ---------------------------------------------
   -- Analyze_Abstract_Subprogram_Declaration --
   ---------------------------------------------

   procedure Analyze_Abstract_Subprogram_Declaration (N : Node_Id) is
      Scop    : constant Entity_Id := Current_Scope;
      Subp_Id : constant Entity_Id :=
                  Analyze_Subprogram_Specification (Specification (N));

   begin
      Generate_Definition (Subp_Id);

      --  Set the SPARK mode from the current context (may be overwritten later
      --  with explicit pragma).

      Set_SPARK_Pragma           (Subp_Id, SPARK_Mode_Pragma);
      Set_SPARK_Pragma_Inherited (Subp_Id);

      --  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     => Subp_Id,
         Checks   => True,
         Warnings => True);

      Set_Is_Abstract_Subprogram (Subp_Id);
      New_Overloaded_Entity (Subp_Id);
      Check_Delayed_Subprogram (Subp_Id);

      Set_Categorization_From_Scope (Subp_Id, Scop);

      if Ekind (Scope (Subp_Id)) = E_Protected_Type then
         Error_Msg_N ("abstract subprogram not allowed in protected type", N);

      --  Issue a warning if the abstract subprogram is neither a dispatching
      --  operation nor an operation that overrides an inherited subprogram or
      --  predefined operator, since this most likely indicates a mistake.

      elsif Warn_On_Redundant_Constructs
        and then not Is_Dispatching_Operation (Subp_Id)
        and then not Present (Overridden_Operation (Subp_Id))
        and then (not Is_Operator_Symbol_Name (Chars (Subp_Id))
                   or else Scop /= Scope (Etype (First_Formal (Subp_Id))))
      then
         Error_Msg_N
           ("abstract subprogram is not dispatching or overriding?r?", N);
      end if;

      Generate_Reference_To_Formals (Subp_Id);
      Check_Eliminated (Subp_Id);

      if Has_Aspects (N) then
         Analyze_Aspect_Specifications (N, Subp_Id);
      end if;
   end Analyze_Abstract_Subprogram_Declaration;

   ---------------------------------
   -- Analyze_Expression_Function --
   ---------------------------------

   procedure Analyze_Expression_Function (N : Node_Id) is
      Expr : constant Node_Id    := Expression (N);
      Loc  : constant Source_Ptr := Sloc (N);
      LocX : constant Source_Ptr := Sloc (Expr);
      Spec : constant Node_Id    := Specification (N);

      --  Local variables

      Asp      : Node_Id;
      New_Body : Node_Id;
      New_Spec : Node_Id;
      Orig_N   : Node_Id;
      Ret      : Node_Id;

      Def_Id : Entity_Id := Empty;
      Prev   : Entity_Id;
      --  If the expression is a completion, Prev is the entity whose
      --  declaration is completed. Def_Id is needed to analyze the spec.

   begin
      --  This is one of the occasions on which we transform the tree during
      --  semantic analysis. If this is a completion, transform the expression
      --  function into an equivalent subprogram body, and analyze it.

      --  Expression functions are inlined unconditionally. The back-end will
      --  determine whether this is possible.

      Inline_Processing_Required := True;

      --  Create a specification for the generated body. This must be done
      --  prior to the analysis of the initial declaration.

      New_Spec := Copy_Subprogram_Spec (Spec);
      Prev     := Current_Entity_In_Scope (Defining_Entity (Spec));

      --  If there are previous overloadable entities with the same name,
      --  check whether any of them is completed by the expression function.
      --  In a generic context a formal subprogram has no completion.

      if Present (Prev)
        and then Is_Overloadable (Prev)
        and then not Is_Formal_Subprogram (Prev)
      then
         Def_Id := Analyze_Subprogram_Specification (Spec);
         Prev   := Find_Corresponding_Spec (N);

         --  The previous entity may be an expression function as well, in
         --  which case the redeclaration is illegal.

         if Present (Prev)
           and then Nkind (Original_Node (Unit_Declaration_Node (Prev))) =
                                                        N_Expression_Function
         then
            Error_Msg_Sloc := Sloc (Prev);
            Error_Msg_N ("& conflicts with declaration#", Def_Id);
            return;
         end if;
      end if;

      Ret := Make_Simple_Return_Statement (LocX, Expr);

      New_Body :=
        Make_Subprogram_Body (Loc,
          Specification              => New_Spec,
          Declarations               => Empty_List,
          Handled_Statement_Sequence =>
            Make_Handled_Sequence_Of_Statements (LocX,
              Statements => New_List (Ret)));
      Set_Was_Expression_Function (New_Body);

      --  If the expression completes a generic subprogram, we must create a
      --  separate node for the body, because at instantiation the original
      --  node of the generic copy must be a generic subprogram body, and
      --  cannot be a expression function. Otherwise we just rewrite the
      --  expression with the non-generic body.

      if Present (Prev) and then Ekind (Prev) = E_Generic_Function then
         Insert_After (N, New_Body);

         --  Propagate any aspects or pragmas that apply to the expression
         --  function to the proper body when the expression function acts
         --  as a completion.

         if Has_Aspects (N) then
            Move_Aspects (N, To => New_Body);
         end if;

         Relocate_Pragmas_To_Body (New_Body);

         Rewrite (N, Make_Null_Statement (Loc));
         Set_Has_Completion (Prev, False);
         Analyze (N);
         Analyze (New_Body);
         Set_Is_Inlined (Prev);

      --  If the expression function is a completion, the previous declaration
      --  must come from source. We know already that it appears in the current
      --  scope. The entity itself may be internally created if within a body
      --  to be inlined.

      elsif Present (Prev)
        and then Is_Overloadable (Prev)
        and then not Is_Formal_Subprogram (Prev)
        and then Comes_From_Source (Parent (Prev))
      then
         Set_Has_Completion (Prev, False);
         Set_Is_Inlined (Prev);

         --  AI12-0103: Expression functions that are a completion freeze their
         --  expression but don't freeze anything else (unlike regular bodies).

         --  Note that we cannot defer this freezing to the analysis of the
         --  expression itself, because a freeze node might appear in a nested
         --  scope, leading to an elaboration order issue in gigi.
         --  As elsewhere, we do not emit freeze nodes within a generic unit.

         if not Inside_A_Generic then
            Freeze_Expr_Types
              (Def_Id => Def_Id,
               Typ    => Etype (Def_Id),
               Expr   => Expr,
               N      => N);
         end if;

         --  For navigation purposes, indicate that the function is a body

         Generate_Reference (Prev, Defining_Entity (N), 'b', Force => True);
         Rewrite (N, New_Body);

         --  Remove any existing aspects from the original node because the act
         --  of rewriting causes the list to be shared between the two nodes.

         Orig_N := Original_Node (N);
         Remove_Aspects (Orig_N);

         --  Propagate any pragmas that apply to expression function to the
         --  proper body when the expression function acts as a completion.
         --  Aspects are automatically transfered because of node rewriting.

         Relocate_Pragmas_To_Body (N);
         Analyze (N);

         --  Prev is the previous entity with the same name, but it is can
         --  be an unrelated spec that is not completed by the expression
         --  function. In that case the relevant entity is the one in the body.
         --  Not clear that the backend can inline it in this case ???

         if Has_Completion (Prev) then

            --  The formals of the expression function are body formals,
            --  and do not appear in the ali file, which will only contain
            --  references to the formals of the original subprogram spec.

            declare
               F1 : Entity_Id;
               F2 : Entity_Id;

            begin
               F1 := First_Formal (Def_Id);
               F2 := First_Formal (Prev);

               while Present (F1) loop
                  Set_Spec_Entity (F1, F2);
                  Next_Formal (F1);
                  Next_Formal (F2);
               end loop;
            end;

         else
            Set_Is_Inlined (Defining_Entity (New_Body));
         end if;

      --  If this is not a completion, create both a declaration and a body, so
      --  that the expression can be inlined whenever possible.

      else
         --  An expression function that is not a completion is not a
         --  subprogram declaration, and thus cannot appear in a protected
         --  definition.

         if Nkind (Parent (N)) = N_Protected_Definition then
            Error_Msg_N
              ("an expression function is not a legal protected operation", N);
         end if;

         Rewrite (N, Make_Subprogram_Declaration (Loc, Specification => Spec));

         --  Remove any existing aspects from the original node because the act
         --  of rewriting causes the list to be shared between the two nodes.

         Orig_N := Original_Node (N);
         Remove_Aspects (Orig_N);

         Analyze (N);

         --  If aspect SPARK_Mode was specified on the body, it needs to be
         --  repeated both on the generated spec and the body.

         Asp := Find_Aspect (Defining_Unit_Name (Spec), Aspect_SPARK_Mode);

         if Present (Asp) then
            Asp := New_Copy_Tree (Asp);
            Set_Analyzed (Asp, False);
            Set_Aspect_Specifications (New_Body, New_List (Asp));
         end if;

         Def_Id := Defining_Entity (N);
         Set_Is_Inlined (Def_Id);

         --  Establish the linkages between the spec and the body. These are
         --  used when the expression function acts as the prefix of attribute
         --  'Access in order to freeze the original expression which has been
         --  moved to the generated body.

         Set_Corresponding_Body (N, Defining_Entity (New_Body));
         Set_Corresponding_Spec (New_Body, Def_Id);

         --  Within a generic preanalyze the original expression for name
         --  capture. The body is also generated but plays no role in
         --  this because it is not part of the original source.
         --  If this is an ignored Ghost entity, analysis of the generated
         --  body is needed to hide external references (as is done in
         --  Analyze_Subprogram_Body) after which the the subprogram profile
         --  can be frozen, which is needed to expand calls to such an ignored
         --  Ghost subprogram.

         if Inside_A_Generic then
            Set_Has_Completion (Def_Id, not Is_Ignored_Ghost_Entity (Def_Id));
            Push_Scope (Def_Id);
            Install_Formals (Def_Id);
            Preanalyze_Spec_Expression (Expr, Etype (Def_Id));
            End_Scope;
         end if;

         --  To prevent premature freeze action, insert the new body at the end
         --  of the current declarations, or at the end of the package spec.
         --  However, resolve usage names now, to prevent spurious visibility
         --  on later entities. Note that the function can now be called in
         --  the current declarative part, which will appear to be prior to
         --  the presence of the body in the code. There are nevertheless no
         --  order of elaboration issues because all name resolution has taken
         --  place at the point of declaration.

         declare
            Decls : List_Id            := List_Containing (N);
            Expr  : constant Node_Id   := Expression (Ret);
            Par   : constant Node_Id   := Parent (Decls);
            Typ   : constant Entity_Id := Etype (Def_Id);

         begin
            --  If this is a wrapper created for in an instance for a formal
            --  subprogram, insert body after declaration, to be analyzed when
            --  the enclosing instance is analyzed.

            if GNATprove_Mode
              and then Is_Generic_Actual_Subprogram (Def_Id)
            then
               Insert_After (N, New_Body);

            else
               if Nkind (Par) = N_Package_Specification
                 and then Decls = Visible_Declarations (Par)
                 and then Present (Private_Declarations (Par))
                 and then not Is_Empty_List (Private_Declarations (Par))
               then
                  Decls := Private_Declarations (Par);
               end if;

               Insert_After (Last (Decls), New_Body);

               --  Preanalyze the expression if not already done above

               if not Inside_A_Generic then
                  Push_Scope (Def_Id);
                  Install_Formals (Def_Id);
                  Preanalyze_Formal_Expression (Expr, Typ);
                  Check_Limited_Return (Original_Node (N), Expr, Typ);
                  End_Scope;
               end if;

               --  In the case of an expression function marked with the
               --  aspect Static, we need to check the requirement that the
               --  function's expression is a potentially static expression.
               --  This is done by making a full copy of the expression tree
               --  and performing a special preanalysis on that tree with
               --  the global flag Checking_Potentially_Static_Expression
               --  enabled. If the resulting expression is static, then it's
               --  OK, but if not, that means the expression violates the
               --  requirements of the Ada 202x RM in 4.9(3.2/5-3.4/5) and
               --  we flag an error.

               if Is_Static_Function (Def_Id) then
                  if not Is_Static_Expression (Expr) then
                     declare
                        Exp_Copy : constant Node_Id := New_Copy_Tree (Expr);
                     begin
                        Set_Checking_Potentially_Static_Expression (True);

                        Preanalyze_Formal_Expression (Exp_Copy, Typ);

                        if not Is_Static_Expression (Exp_Copy) then
                           Error_Msg_N
                             ("static expression function requires "
                                & "potentially static expression", Expr);
                        end if;

                        Set_Checking_Potentially_Static_Expression (False);
                     end;
                  end if;

                  --  We also make an additional copy of the expression and
                  --  replace the expression of the expression function with
                  --  this copy, because the currently present expression is
                  --  now associated with the body created for the static
                  --  expression function, which will later be analyzed and
                  --  possibly rewritten, and we need to have the separate
                  --  unanalyzed copy available for use with later static
                  --  calls.

                  Set_Expression
                    (Original_Node (Subprogram_Spec (Def_Id)),
                     New_Copy_Tree (Expr));

                  --  Mark static expression functions as inlined, to ensure
                  --  that even calls with nonstatic actuals will be inlined.

                  Set_Has_Pragma_Inline (Def_Id);
                  Set_Is_Inlined (Def_Id);
               end if;
            end if;
         end;
      end if;

      --  Check incorrect use of dynamically tagged expression. This doesn't
      --  fall out automatically when analyzing the generated function body,
      --  because Check_Dynamically_Tagged_Expression deliberately ignores
      --  nodes that don't come from source.

      if Present (Def_Id)
        and then Nkind (Def_Id) in N_Has_Etype
        and then Is_Tagged_Type (Etype (Def_Id))
      then
         Check_Dynamically_Tagged_Expression
           (Expr        => Expr,
            Typ         => Etype (Def_Id),
            Related_Nod => Original_Node (N));
      end if;

      --  We must enforce checks for unreferenced formals in our newly
      --  generated function, so we propagate the referenced flag from the
      --  original spec to the new spec as well as setting Comes_From_Source.

      if Present (Parameter_Specifications (New_Spec)) then
         declare
            Form_New_Def  : Entity_Id;
            Form_New_Spec : Entity_Id;
            Form_Old_Def  : Entity_Id;
            Form_Old_Spec : Entity_Id;

         begin
            Form_New_Spec := First (Parameter_Specifications (New_Spec));
            Form_Old_Spec := First (Parameter_Specifications (Spec));

            while Present (Form_New_Spec) and then Present (Form_Old_Spec) loop
               Form_New_Def := Defining_Identifier (Form_New_Spec);
               Form_Old_Def := Defining_Identifier (Form_Old_Spec);

               Set_Comes_From_Source (Form_New_Def, True);

               --  Because of the usefulness of unreferenced controlling
               --  formals we exempt them from unreferenced warnings by marking
               --  them as always referenced.

               Set_Referenced (Form_Old_Def,
                 (Is_Formal (Form_Old_Def)
                    and then Is_Controlling_Formal (Form_Old_Def))
                  or else Referenced (Form_Old_Def));

               Next (Form_New_Spec);
               Next (Form_Old_Spec);
            end loop;
         end;
      end if;
   end Analyze_Expression_Function;

   ---------------------------------------
   -- Analyze_Extended_Return_Statement --
   ---------------------------------------

   procedure Analyze_Extended_Return_Statement (N : Node_Id) is
   begin
      Check_Compiler_Unit ("extended return statement", N);
      Analyze_Return_Statement (N);
   end Analyze_Extended_Return_Statement;

   ----------------------------
   -- Analyze_Function_Call  --
   ----------------------------

   procedure Analyze_Function_Call (N : Node_Id) is
      Actuals  : constant List_Id := Parameter_Associations (N);
      Func_Nam : constant Node_Id := Name (N);
      Actual   : Node_Id;

   begin
      Analyze (Func_Nam);

      --  A call of the form A.B (X) may be an Ada 2005 call, which is
      --  rewritten as B (A, X). If the rewriting is successful, the call
      --  has been analyzed and we just return.

      if Nkind (Func_Nam) = N_Selected_Component
        and then Name (N) /= Func_Nam
        and then Is_Rewrite_Substitution (N)
        and then Present (Etype (N))
      then
         return;
      end if;

      --  If error analyzing name, then set Any_Type as result type and return

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

      --  Otherwise analyze the parameters

      if Present (Actuals) then
         Actual := First (Actuals);
         while Present (Actual) loop
            Analyze (Actual);
            Check_Parameterless_Call (Actual);
            Next (Actual);
         end loop;
      end if;

      Analyze_Call (N);
   end Analyze_Function_Call;

   -----------------------------
   -- Analyze_Function_Return --
   -----------------------------

   procedure Analyze_Function_Return (N : Node_Id) is
      Loc        : constant Source_Ptr := Sloc (N);
      Stm_Entity : constant Entity_Id  := Return_Statement_Entity (N);
      Scope_Id   : constant Entity_Id  := Return_Applies_To (Stm_Entity);

      R_Type : constant Entity_Id := Etype (Scope_Id);
      --  Function result subtype

      procedure Check_No_Return_Expression (Return_Expr : Node_Id);
      --  Ada 2020: Check that the return expression in a No_Return function
      --  meets the conditions specified by RM 6.5.1(5.1/5).

      procedure Check_Return_Construct_Accessibility (Return_Stmt : Node_Id);
      --  Apply legality rule of 6.5 (5.9) to the access discriminants of an
      --  aggregate in a return statement.

      procedure Check_Return_Subtype_Indication (Obj_Decl : Node_Id);
      --  Check that the return_subtype_indication properly matches the result
      --  subtype of the function, as required by RM-6.5(5.1/2-5.3/2).

      --------------------------------
      -- Check_No_Return_Expression --
      --------------------------------

      procedure Check_No_Return_Expression (Return_Expr : Node_Id) is
         Kind : constant Node_Kind := Nkind (Return_Expr);

      begin
         if Kind = N_Raise_Expression then
            return;

         elsif Kind = N_Function_Call
           and then Is_Entity_Name (Name (Return_Expr))
           and then Ekind (Entity (Name (Return_Expr))) in
                      E_Function | E_Generic_Function
           and then No_Return (Entity (Name (Return_Expr)))
         then
            return;
         end if;

         Error_Msg_N
           ("illegal expression in RETURN statement of No_Return function",
            Return_Expr);
         Error_Msg_N
           ("\must be raise expression or call to No_Return (RM 6.5.1(5.1/5))",
            Return_Expr);
      end Check_No_Return_Expression;

      ------------------------------------------
      -- Check_Return_Construct_Accessibility --
      ------------------------------------------

      procedure Check_Return_Construct_Accessibility (Return_Stmt : Node_Id) is

         function First_Selector (Assoc : Node_Id) return Node_Id;
         --  Obtain the first selector or choice from a given association

         --------------------
         -- First_Selector --
         --------------------

         function First_Selector (Assoc : Node_Id) return Node_Id is
         begin
            if Nkind (Assoc) = N_Component_Association then
               return First (Choices (Assoc));

            elsif Nkind (Assoc) = N_Discriminant_Association then
               return (First (Selector_Names (Assoc)));

            else
               raise Program_Error;
            end if;
         end First_Selector;

         --  Local declarations

         Assoc : Node_Id := Empty;
         --  Assoc should perhaps be renamed and declared as a
         --  Node_Or_Entity_Id since it encompasses not only component and
         --  discriminant associations, but also discriminant components within
         --  a type declaration or subtype indication ???

         Assoc_Expr    : Node_Id;
         Assoc_Present : Boolean := False;

         Unseen_Disc_Count : Nat := 0;
         Seen_Discs        : Elist_Id;
         Disc              : Entity_Id;
         First_Disc        : Entity_Id;

         Obj_Decl   : Node_Id;
         Return_Con : Node_Id;
         Unqual     : Node_Id;

      --  Start of processing for Check_Return_Construct_Accessibility

      begin
         --  Only perform checks on record types with access discriminants and
         --  non-internally generated functions.

         if not Is_Record_Type (R_Type)
           or else not Has_Anonymous_Access_Discriminant (R_Type)
           or else not Comes_From_Source (Return_Stmt)
         then
            return;
         end if;

         --  We are only interested in return statements

         if Nkind (Return_Stmt) not in
              N_Extended_Return_Statement | N_Simple_Return_Statement
         then
            return;
         end if;

         --  Fetch the object from the return statement, in the case of a
         --  simple return statement the expression is part of the node.

         if Nkind (Return_Stmt) = N_Extended_Return_Statement then
            --  Obtain the object definition from the expanded extended return

            Return_Con := First (Return_Object_Declarations (Return_Stmt));
            while Present (Return_Con) loop
               --  Inspect the original node to avoid object declarations
               --  expanded into renamings.

               if Nkind (Original_Node (Return_Con)) = N_Object_Declaration
                 and then Comes_From_Source (Original_Node (Return_Con))
               then
                  exit;
               end if;

               Nlists.Next (Return_Con);
            end loop;

            pragma Assert (Present (Return_Con));

            --  Could be dealing with a renaming

            Return_Con := Original_Node (Return_Con);
         else
            Return_Con := Expression (Return_Stmt);
         end if;

         --  Obtain the accessibility levels of the expressions associated
         --  with all anonymous access discriminants, then generate a
         --  dynamic check or static error when relevant.

         Unqual := Unqualify (Original_Node (Return_Con));

         --  Get the corresponding declaration based on the return object's
         --  identifier.

         if Nkind (Unqual) = N_Identifier
           and then Nkind (Parent (Entity (Unqual)))
                      in N_Object_Declaration
                       | N_Object_Renaming_Declaration
         then
            Obj_Decl := Original_Node (Parent (Entity (Unqual)));

         --  We were passed the object declaration directly, so use it

         elsif Nkind (Unqual) in N_Object_Declaration
                               | N_Object_Renaming_Declaration
         then
            Obj_Decl := Unqual;

         --  Otherwise, we are looking at something else

         else
            Obj_Decl := Empty;

         end if;

         --  Hop up object renamings when present

         if Present (Obj_Decl)
           and then Nkind (Obj_Decl) = N_Object_Renaming_Declaration
         then
            while Nkind (Obj_Decl) = N_Object_Renaming_Declaration loop

               if Nkind (Name (Obj_Decl)) not in N_Entity then
                  --  We may be looking at the expansion of iterators or
                  --  some other internally generated construct, so it is safe
                  --  to ignore checks ???

                  if not Comes_From_Source (Obj_Decl) then
                     return;
                  end if;

                  Obj_Decl := Original_Node
                                (Declaration_Node
                                  (Ultimate_Prefix (Name (Obj_Decl))));

               --  Move up to the next declaration based on the object's name

               else
                  Obj_Decl := Original_Node
                                (Declaration_Node (Name (Obj_Decl)));
               end if;
            end loop;
         end if;

         --  Obtain the discriminant values from the return aggregate

         --  Do we cover extension aggregates correctly ???

         if Nkind (Unqual) = N_Aggregate then
            if Present (Expressions (Unqual)) then
               Assoc := First (Expressions (Unqual));
            else
               Assoc := First (Component_Associations (Unqual));
            end if;

         --  There is an object declaration for the return object

         elsif Present (Obj_Decl) then
            --  When a subtype indication is present in an object declaration
            --  it must contain the object's discriminants.

            if Nkind (Object_Definition (Obj_Decl)) = N_Subtype_Indication then
               Assoc := First
                          (Constraints
                            (Constraint
                              (Object_Definition (Obj_Decl))));

            --  The object declaration contains an aggregate

            elsif Present (Expression (Obj_Decl)) then

               if Nkind (Unqualify (Expression (Obj_Decl))) = N_Aggregate then
                  --  Grab the first associated discriminant expresion

                  if Present
                       (Expressions (Unqualify (Expression (Obj_Decl))))
                  then
                     Assoc := First
                                (Expressions
                                  (Unqualify (Expression (Obj_Decl))));
                  else
                     Assoc := First
                                (Component_Associations
                                  (Unqualify (Expression (Obj_Decl))));
                  end if;

               --  Otherwise, this is something else

               else
                  return;
               end if;

            --  There are no supplied discriminants in the object declaration,
            --  so get them from the type definition since they must be default
            --  initialized.

            --  Do we handle constrained subtypes correctly ???

            elsif Nkind (Unqual) = N_Object_Declaration then
               Assoc := First_Discriminant
                          (Etype (Object_Definition (Obj_Decl)));

            else
               Assoc := First_Discriminant (Etype (Unqual));
            end if;

         --  When we are not looking at an aggregate or an identifier, return
         --  since any other construct (like a function call) is not
         --  applicable since checks will be performed on the side of the
         --  callee.

         else
            return;
         end if;

         --  Obtain the discriminants so we know the actual type in case the
         --  value of their associated expression gets implicitly converted.

         if No (Obj_Decl) then
            pragma Assert (Nkind (Unqual) = N_Aggregate);

            Disc := First_Discriminant (Etype (Unqual));

         else
            Disc := First_Discriminant
                      (Etype (Defining_Identifier (Obj_Decl)));
         end if;

         --  Preserve the first discriminant for checking named associations

         First_Disc := Disc;

         --  Count the number of discriminants for processing an aggregate
         --  which includes an others.

         Disc := First_Disc;
         while Present (Disc) loop
            Unseen_Disc_Count := Unseen_Disc_Count + 1;

            Next_Discriminant (Disc);
         end loop;

         Seen_Discs := New_Elmt_List;

         --  Loop through each of the discriminants and check each expression
         --  associated with an anonymous access discriminant.

         --  When named associations occur in the return aggregate then
         --  discriminants can be in any order, so we need to ensure we do
         --  not continue to loop when all discriminants have been seen.

         Disc := First_Disc;
         while Present (Assoc)
           and then (Present (Disc) or else Assoc_Present)
           and then Unseen_Disc_Count > 0
         loop
            --  Handle named associations by searching through the names of
            --  the relevant discriminant components.

            if Nkind (Assoc)
                 in N_Component_Association | N_Discriminant_Association
            then
               Assoc_Expr    := Expression (Assoc);
               Assoc_Present := True;

               --  We currently don't handle box initialized discriminants,
               --  however, since default initialized anonymous access
               --  discriminants are a corner case, this is ok for now ???

               if Nkind (Assoc) = N_Component_Association
                 and then Box_Present (Assoc)
               then
                  Assoc_Present := False;

                  if Nkind (First_Selector (Assoc)) = N_Others_Choice then
                     Unseen_Disc_Count := 0;
                  end if;

               --  When others is present we must identify a discriminant we
               --  haven't already seen so as to get the appropriate type for
               --  the static accessibility check.

               --  This works because all components within an others clause
               --  must have the same type.

               elsif Nkind (First_Selector (Assoc)) = N_Others_Choice then

                  Disc := First_Disc;
                  Outer : while Present (Disc) loop
                     declare
                        Current_Seen_Disc : Elmt_Id;
                     begin
                        --  Move through the list of identified discriminants

                        Current_Seen_Disc := First_Elmt (Seen_Discs);
                        while Present (Current_Seen_Disc) loop
                           --  Exit the loop when we found a match

                           exit when
                             Chars (Node (Current_Seen_Disc)) = Chars (Disc);

                           Next_Elmt (Current_Seen_Disc);
                        end loop;

                        --  When we have exited the above loop without finding
                        --  a match then we know that Disc has not been seen.

                        exit Outer when No (Current_Seen_Disc);
                     end;

                     Next_Discriminant (Disc);
                  end loop Outer;

                  --  If we got to an others clause with a non-zero
                  --  discriminant count there must be a discriminant left to
                  --  check.

                  pragma Assert (Present (Disc));

                  --  Set the unseen discriminant count to zero because we know
                  --  an others clause sets all remaining components of an
                  --  aggregate.

                  Unseen_Disc_Count := 0;

               --  Move through each of the selectors in the named association
               --  and obtain a discriminant for accessibility checking if one
               --  is referenced in the list. Also track which discriminants
               --  are referenced for the purpose of handling an others clause.

               else
                  declare
                     Assoc_Choice : Node_Id;
                     Curr_Disc    : Node_Id;
                  begin

                     Disc      := Empty;
                     Curr_Disc := First_Disc;
                     while Present (Curr_Disc) loop
                        --  Check each of the choices in the associations for a
                        --  match to the name of the current discriminant.

                        Assoc_Choice := First_Selector (Assoc);
                        while Present (Assoc_Choice) loop
                           --  When the name matches we track that we have seen
                           --  the discriminant, but instead of exiting the
                           --  loop we continue iterating to make sure all the
                           --  discriminants within the named association get
                           --  tracked.

                           if Chars (Assoc_Choice) = Chars (Curr_Disc) then
                              Append_Elmt (Curr_Disc, Seen_Discs);

                              Disc              := Curr_Disc;
                              Unseen_Disc_Count := Unseen_Disc_Count - 1;
                           end if;

                           Next (Assoc_Choice);
                        end loop;

                        Next_Discriminant (Curr_Disc);
                     end loop;
                  end;
               end if;

            --  Unwrap the associated expression if we are looking at a default
            --  initialized type declaration. In this case Assoc is not really
            --  an association, but a component declaration. Should Assoc be
            --  renamed in some way to be more clear ???

            --  This occurs when the return object does not initialize
            --  discriminant and instead relies on the type declaration for
            --  their supplied values.

            elsif Nkind (Assoc) in N_Entity
              and then Ekind (Assoc) = E_Discriminant
            then
               Append_Elmt (Disc, Seen_Discs);

               Assoc_Expr        := Discriminant_Default_Value (Assoc);
               Unseen_Disc_Count := Unseen_Disc_Count - 1;

            --  Otherwise, there is nothing to do because Assoc is an
            --  expression within the return aggregate itself.

            else
               Append_Elmt (Disc, Seen_Discs);

               Assoc_Expr        := Assoc;
               Unseen_Disc_Count := Unseen_Disc_Count - 1;
            end if;

            --  Check the accessibility level of the expression when the
            --  discriminant is of an anonymous access type.

            if Present (Assoc_Expr)
              and then Present (Disc)
              and then Ekind (Etype (Disc)) = E_Anonymous_Access_Type
            then
               --  Perform a static check first, if possible

               if Static_Accessibility_Level
                    (Expr              => Assoc_Expr,
                     Level             => Zero_On_Dynamic_Level,
                     In_Return_Context => True)
                      > Scope_Depth (Scope (Scope_Id))
               then
                  Error_Msg_N
                    ("access discriminant in return object would be a dangling"
                     & " reference", Return_Stmt);

                  exit;
               end if;

               --  Otherwise, generate a dynamic check based on the extra
               --  accessibility of the result.

               if Present (Extra_Accessibility_Of_Result (Scope_Id)) then
                  Insert_Before_And_Analyze (Return_Stmt,
                    Make_Raise_Program_Error (Loc,
                      Condition =>
                        Make_Op_Gt (Loc,
                          Left_Opnd  => Accessibility_Level
                                          (Expr              => Assoc_Expr,
                                           Level             => Dynamic_Level,
                                           In_Return_Context => True),
                          Right_Opnd => Extra_Accessibility_Of_Result
                                          (Scope_Id)),
                      Reason    => PE_Accessibility_Check_Failed));
               end if;
            end if;

            --  Iterate over the discriminants, except when we have encountered
            --  a named association since the discriminant order becomes
            --  irrelevant in that case.

            if not Assoc_Present then
               Next_Discriminant (Disc);
            end if;

            --  Iterate over associations

            if not Is_List_Member (Assoc) then
               exit;
            else
               Nlists.Next (Assoc);
            end if;
         end loop;
      end Check_Return_Construct_Accessibility;

      -------------------------------------
      -- Check_Return_Subtype_Indication --
      -------------------------------------

      procedure Check_Return_Subtype_Indication (Obj_Decl : Node_Id) is
         Return_Obj : constant Node_Id   := Defining_Identifier (Obj_Decl);

         R_Stm_Type : constant Entity_Id := Etype (Return_Obj);
         --  Subtype given in the extended return statement (must match R_Type)

         Subtype_Ind : constant Node_Id :=
                         Object_Definition (Original_Node (Obj_Decl));

         procedure Error_No_Match (N : Node_Id);
         --  Output error messages for case where types do not statically
         --  match. N is the location for the messages.

         --------------------
         -- Error_No_Match --
         --------------------

         procedure Error_No_Match (N : Node_Id) is
         begin
            Error_Msg_N
              ("subtype must statically match function result subtype", N);

            if not Predicates_Match (R_Stm_Type, R_Type) then
               Error_Msg_Node_2 := R_Type;
               Error_Msg_NE
                 ("\predicate of& does not match predicate of&",
                  N, R_Stm_Type);
            end if;
         end Error_No_Match;

      --  Start of processing for Check_Return_Subtype_Indication

      begin
         --  First, avoid cascaded errors

         if Error_Posted (Obj_Decl) or else Error_Posted (Subtype_Ind) then
            return;
         end if;

         --  "return access T" case; check that the return statement also has
         --  "access T", and that the subtypes statically match:
         --   if this is an access to subprogram the signatures must match.

         if Is_Anonymous_Access_Type (R_Type) then
            if Is_Anonymous_Access_Type (R_Stm_Type) then
               if Ekind (Designated_Type (R_Stm_Type)) /= E_Subprogram_Type
               then
                  if Base_Type (Designated_Type (R_Stm_Type)) /=
                     Base_Type (Designated_Type (R_Type))
                    or else not Subtypes_Statically_Match (R_Stm_Type, R_Type)
                  then
                     Error_No_Match (Subtype_Mark (Subtype_Ind));
                  end if;

               else
                  --  For two anonymous access to subprogram types, the types
                  --  themselves must be type conformant.

                  if not Conforming_Types
                           (R_Stm_Type, R_Type, Fully_Conformant)
                  then
                     Error_No_Match (Subtype_Ind);
                  end if;
               end if;

            else
               Error_Msg_N ("must use anonymous access type", Subtype_Ind);
            end if;

         --  If the return object is of an anonymous access type, then report
         --  an error if the function's result type is not also anonymous.

         elsif Is_Anonymous_Access_Type (R_Stm_Type) then
            pragma Assert (not Is_Anonymous_Access_Type (R_Type));
            Error_Msg_N
              ("anonymous access not allowed for function with named access "
               & "result", Subtype_Ind);

         --  Subtype indication case: check that the return object's type is
         --  covered by the result type, and that the subtypes statically match
         --  when the result subtype is constrained. Also handle record types
         --  with unknown discriminants for which we have built the underlying
         --  record view. Coverage is needed to allow specific-type return
         --  objects when the result type is class-wide (see AI05-32).

         elsif Covers (Base_Type (R_Type), Base_Type (R_Stm_Type))
           or else (Is_Underlying_Record_View (Base_Type (R_Stm_Type))
                     and then
                       Covers
                         (Base_Type (R_Type),
                          Underlying_Record_View (Base_Type (R_Stm_Type))))
         then
            --  A null exclusion may be present on the return type, on the
            --  function specification, on the object declaration or on the
            --  subtype itself.

            if Is_Access_Type (R_Type)
              and then
                (Can_Never_Be_Null (R_Type)
                  or else Null_Exclusion_Present (Parent (Scope_Id))) /=
                            Can_Never_Be_Null (R_Stm_Type)
            then
               Error_No_Match (Subtype_Ind);
            end if;

            --  AI05-103: for elementary types, subtypes must statically match

            if Is_Constrained (R_Type) or else Is_Access_Type (R_Type) then
               if not Subtypes_Statically_Match (R_Stm_Type, R_Type) then
                  Error_No_Match (Subtype_Ind);
               end if;
            end if;

         --  All remaining cases are illegal

         --  Note: previous versions of this subprogram allowed the return
         --  value to be the ancestor of the return type if the return type
         --  was a null extension. This was plainly incorrect.

         else
            Error_Msg_N
              ("wrong type for return_subtype_indication", Subtype_Ind);
         end if;
      end Check_Return_Subtype_Indication;

      ---------------------
      -- Local Variables --
      ---------------------

      Expr     : Node_Id;
      Obj_Decl : Node_Id := Empty;

   --  Start of processing for Analyze_Function_Return

   begin
      Set_Return_Present (Scope_Id);

      if Nkind (N) = N_Simple_Return_Statement then
         Expr := Expression (N);

         --  Guard against a malformed expression. The parser may have tried to
         --  recover but the node is not analyzable.

         if Nkind (Expr) = N_Error then
            Set_Etype (Expr, Any_Type);
            Expander_Mode_Save_And_Set (False);
            return;

         else
            --  The resolution of a controlled [extension] aggregate associated
            --  with a return statement creates a temporary which needs to be
            --  finalized on function exit. Wrap the return statement inside a
            --  block so that the finalization machinery can detect this case.
            --  This early expansion is done only when the return statement is
            --  not part of a handled sequence of statements.

            if Nkind (Expr) in N_Aggregate | N_Extension_Aggregate
              and then Needs_Finalization (R_Type)
              and then Nkind (Parent (N)) /= N_Handled_Sequence_Of_Statements
            then
               Rewrite (N,
                 Make_Block_Statement (Loc,
                   Handled_Statement_Sequence =>
                     Make_Handled_Sequence_Of_Statements (Loc,
                       Statements => New_List (Relocate_Node (N)))));

               Analyze (N);
               return;
            end if;

            Analyze (Expr);

            --  Ada 2005 (AI-251): If the type of the returned object is
            --  an access to an interface type then we add an implicit type
            --  conversion to force the displacement of the "this" pointer to
            --  reference the secondary dispatch table. We cannot delay the
            --  generation of this implicit conversion until the expansion
            --  because in this case the type resolution changes the decoration
            --  of the expression node to match R_Type; by contrast, if the
            --  returned object is a class-wide interface type then it is too
            --  early to generate here the implicit conversion since the return
            --  statement may be rewritten by the expander into an extended
            --  return statement whose expansion takes care of adding the
            --  implicit type conversion to displace the pointer to the object.

            if Expander_Active
              and then Serious_Errors_Detected = 0
              and then Is_Access_Type (R_Type)
              and then Nkind (Expr) not in N_Null | N_Raise_Expression
              and then Is_Interface (Designated_Type (R_Type))
              and then Is_Progenitor (Designated_Type (R_Type),
                                      Designated_Type (Etype (Expr)))
            then
               Rewrite (Expr, Convert_To (R_Type, Relocate_Node (Expr)));
               Analyze (Expr);
            end if;

            Resolve (Expr, R_Type);
            Check_Limited_Return (N, Expr, R_Type);

            Check_Return_Construct_Accessibility (N);

            --  Ada 2020 (AI12-0269): Any return statement that applies to a
            --  nonreturning function shall be a simple_return_statement with
            --  an expression that is a raise_expression, or else a call on a
            --  nonreturning function, or else a parenthesized expression of
            --  one of these.

            if Ada_Version >= Ada_2020
              and then No_Return (Scope_Id)
              and then Comes_From_Source (N)
            then
               Check_No_Return_Expression (Original_Node (Expr));
            end if;
         end if;
      else
         Obj_Decl := Last (Return_Object_Declarations (N));

         --  Analyze parts specific to extended_return_statement:

         declare
            Has_Aliased : constant Boolean := Aliased_Present (Obj_Decl);
            HSS         : constant Node_Id := Handled_Statement_Sequence (N);

         begin
            Expr := Expression (Obj_Decl);

            --  Note: The check for OK_For_Limited_Init will happen in
            --  Analyze_Object_Declaration; we treat it as a normal
            --  object declaration.

            Set_Is_Return_Object (Defining_Identifier (Obj_Decl));

            --  Returning a build-in-place unconstrained array type we defer
            --  the full analysis of the returned object to avoid generating
            --  the corresponding constrained subtype; otherwise the bounds
            --  would be created in the stack and a dangling reference would
            --  be returned pointing to the bounds. We perform its preanalysis
            --  to report errors on the initializing aggregate now (if any);
            --  we also ensure its activation chain and Master variable are
            --  defined (if tasks are being declared) since they are generated
            --  as part of the analysis and expansion of the object declaration
            --  at this stage.

            if Is_Array_Type (R_Type)
              and then not Is_Constrained (R_Type)
              and then Is_Build_In_Place_Function (Scope_Id)
              and then Needs_BIP_Alloc_Form (Scope_Id)
              and then Nkind (Expr) in N_Aggregate | N_Extension_Aggregate
            then
               Preanalyze (Obj_Decl);

               if Expander_Active then
                  Ensure_Activation_Chain_And_Master (Obj_Decl);
               end if;

            else
               Analyze (Obj_Decl);
            end if;

            Check_Return_Subtype_Indication (Obj_Decl);

            if Present (HSS) then
               Analyze (HSS);

               if Present (Exception_Handlers (HSS)) then

                  --  ???Has_Nested_Block_With_Handler needs to be set.
                  --  Probably by creating an actual N_Block_Statement.
                  --  Probably in Expand.

                  null;
               end if;
            end if;

            --  Mark the return object as referenced, since the return is an
            --  implicit reference of the object.

            Set_Referenced (Defining_Identifier (Obj_Decl));

            Check_References (Stm_Entity);

            Check_Return_Construct_Accessibility (N);

            --  Check RM 6.5 (5.9/3)

            if Has_Aliased then
               if Ada_Version < Ada_2012 then

                  --  Shouldn't this test Warn_On_Ada_2012_Compatibility ???
                  --  Can it really happen (extended return???)

                  Error_Msg_N
                    ("ALIASED only allowed for limited return objects "
                     & "in Ada 2012??", N);

               elsif not Is_Limited_View (R_Type) then
                  Error_Msg_N
                    ("ALIASED only allowed for limited return objects", N);
               end if;
            end if;

            --  Ada 2020 (AI12-0269): Any return statement that applies to a
            --  nonreturning function shall be a simple_return_statement.

            if Ada_Version >= Ada_2020
              and then No_Return (Scope_Id)
              and then Comes_From_Source (N)
            then
               Error_Msg_N
                 ("extended RETURN statement not allowed in No_Return "
                  & "function", N);
            end if;
         end;
      end if;

      --  Case of Expr present

      if Present (Expr) then

         --  Defend against previous errors

         if Nkind (Expr) = N_Empty
           or else No (Etype (Expr))
         then
            return;
         end if;

         --  Apply constraint check. Note that this is done before the implicit
         --  conversion of the expression done for anonymous access types to
         --  ensure correct generation of the null-excluding check associated
         --  with null-excluding expressions found in return statements. We
         --  don't need a check if the subtype of the return object is the
         --  same as the result subtype of the function.

         if Nkind (N) /= N_Extended_Return_Statement
           or else Nkind (Obj_Decl) /= N_Object_Declaration
           or else Nkind (Object_Definition (Obj_Decl)) not in N_Has_Entity
           or else Entity (Object_Definition (Obj_Decl)) /= R_Type
         then
            Apply_Constraint_Check (Expr, R_Type);
         end if;

         --  The return value is converted to the return type of the function,
         --  which implies a predicate check if the return type is predicated.
         --  We do not apply the check for an extended return statement because
         --  Analyze_Object_Declaration has already done it on Obj_Decl above.
         --  We do not apply the check to a case expression because it will
         --  be expanded into a series of return statements, each of which
         --  will receive a predicate check.

         if Nkind (N) /= N_Extended_Return_Statement
           and then Nkind (Expr) /= N_Case_Expression
         then
            Apply_Predicate_Check (Expr, R_Type);
         end if;

         --  Ada 2005 (AI-318-02): When the result type is an anonymous access
         --  type, apply an implicit conversion of the expression to that type
         --  to force appropriate static and run-time accessibility checks.
         --  But we want to apply the checks to an extended return statement
         --  only once, i.e. not to the simple return statement generated at
         --  the end of its expansion because, prior to leaving the function,
         --  the accessibility level of the return object changes to be a level
         --  determined by the point of call (RM 3.10.2(10.8/3)).

         if Ada_Version >= Ada_2005
           and then Ekind (R_Type) = E_Anonymous_Access_Type
           and then (Nkind (N) = N_Extended_Return_Statement
                     or else not Comes_From_Extended_Return_Statement (N))
         then
            Rewrite (Expr, Convert_To (R_Type, Relocate_Node (Expr)));
            Analyze_And_Resolve (Expr, R_Type);

         --  If this is a local anonymous access to subprogram, the
         --  accessibility check can be applied statically. The return is
         --  illegal if the access type of the return expression is declared
         --  inside of the subprogram (except if it is the subtype indication
         --  of an extended return statement).

         elsif Ekind (R_Type) = E_Anonymous_Access_Subprogram_Type then
            if not Comes_From_Source (Current_Scope)
              or else Ekind (Current_Scope) = E_Return_Statement
            then
               null;

            elsif
                Scope_Depth (Scope (Etype (Expr))) >= Scope_Depth (Scope_Id)
            then
               Error_Msg_N ("cannot return local access to subprogram", N);
            end if;

         --  The expression cannot be of a formal incomplete type

         elsif Ekind (Etype (Expr)) = E_Incomplete_Type
           and then Is_Generic_Type (Etype (Expr))
         then
            Error_Msg_N
              ("cannot return expression of a formal incomplete type", N);
         end if;

         --  If the result type is class-wide, then check that the return
         --  expression's type is not declared at a deeper level than the
         --  function (RM05-6.5(5.6/2)).

         if Ada_Version >= Ada_2005
           and then Is_Class_Wide_Type (R_Type)
         then
            if Type_Access_Level (Etype (Expr)) >
                 Subprogram_Access_Level (Scope_Id)
            then
               Error_Msg_N
                 ("level of return expression type is deeper than "
                  & "class-wide function!", Expr);
            end if;
         end if;

         --  Check incorrect use of dynamically tagged expression

         if Is_Tagged_Type (R_Type) then
            Check_Dynamically_Tagged_Expression
              (Expr => Expr,
               Typ  => R_Type,
               Related_Nod => N);
         end if;

         --  ??? A real run-time accessibility check is needed in cases
         --  involving dereferences of access parameters. For now we just
         --  check the static cases.

         if (Ada_Version < Ada_2005 or else Debug_Flag_Dot_L)
           and then Is_Limited_View (Etype (Scope_Id))
           and then Static_Accessibility_Level (Expr, Zero_On_Dynamic_Level)
                      > Subprogram_Access_Level (Scope_Id)
         then
            --  Suppress the message in a generic, where the rewriting
            --  is irrelevant.

            if Inside_A_Generic then
               null;

            else
               Rewrite (N,
                 Make_Raise_Program_Error (Loc,
                   Reason => PE_Accessibility_Check_Failed));
               Analyze (N);

               Error_Msg_Warn := SPARK_Mode /= On;
               Error_Msg_N ("cannot return a local value by reference<<", N);
               Error_Msg_NE ("\& [<<", N, Standard_Program_Error);
            end if;
         end if;

         if Known_Null (Expr)
           and then Nkind (Parent (Scope_Id)) = N_Function_Specification
           and then Null_Exclusion_Present (Parent (Scope_Id))
         then
            Apply_Compile_Time_Constraint_Error
              (N      => Expr,
               Msg    => "(Ada 2005) null not allowed for "
                         & "null-excluding return??",
               Reason => CE_Null_Not_Allowed);
         end if;

      --  RM 6.5 (5.4/3): accessibility checks also apply if the return object
      --  has no initializing expression.

      elsif Ada_Version > Ada_2005 and then Is_Class_Wide_Type (R_Type) then
         if Type_Access_Level (Etype (Defining_Identifier (Obj_Decl))) >
              Subprogram_Access_Level (Scope_Id)
         then
            Error_Msg_N
              ("level of return expression type is deeper than "
               & "class-wide function!", Obj_Decl);
         end if;
      end if;
   end Analyze_Function_Return;

   -------------------------------------
   -- Analyze_Generic_Subprogram_Body --
   -------------------------------------

   procedure Analyze_Generic_Subprogram_Body
     (N      : Node_Id;
      Gen_Id : Entity_Id)
   is
      Gen_Decl : constant Node_Id     := Unit_Declaration_Node (Gen_Id);
      Kind     : constant Entity_Kind := Ekind (Gen_Id);
      Body_Id  : Entity_Id;
      New_N    : Node_Id;
      Spec     : Node_Id;

   begin
      --  Copy body and disable expansion while analyzing the generic For a
      --  stub, do not copy the stub (which would load the proper body), this
      --  will be done when the proper body is analyzed.

      if Nkind (N) /= N_Subprogram_Body_Stub then
         New_N := Copy_Generic_Node (N, Empty, Instantiating => False);
         Rewrite (N, New_N);

         --  Once the contents of the generic copy and the template are
         --  swapped, do the same for their respective aspect specifications.

         Exchange_Aspects (N, New_N);

         --  Collect all contract-related source pragmas found within the
         --  template and attach them to the contract of the subprogram body.
         --  This contract is used in the capture of global references within
         --  annotations.

         Create_Generic_Contract (N);

         Start_Generic;
      end if;

      Spec := Specification (N);

      --  Within the body of the generic, the subprogram is callable, and
      --  behaves like the corresponding non-generic unit.

      Body_Id := Defining_Entity (Spec);

      if Kind = E_Generic_Procedure
        and then Nkind (Spec) /= N_Procedure_Specification
      then
         Error_Msg_N ("invalid body for generic procedure", Body_Id);
         return;

      elsif Kind = E_Generic_Function
        and then Nkind (Spec) /= N_Function_Specification
      then
         Error_Msg_N ("invalid body for generic function", Body_Id);
         return;
      end if;

      Set_Corresponding_Body (Gen_Decl, Body_Id);

      if Has_Completion (Gen_Id)
        and then Nkind (Parent (N)) /= N_Subunit
      then
         Error_Msg_N ("duplicate generic body", N);
         return;
      else
         Set_Has_Completion (Gen_Id);
      end if;

      if Nkind (N) = N_Subprogram_Body_Stub then
         Mutate_Ekind (Defining_Entity (Specification (N)), Kind);
      else
         Set_Corresponding_Spec (N, Gen_Id);
      end if;

      if Nkind (Parent (N)) = N_Compilation_Unit then
         Set_Cunit_Entity (Current_Sem_Unit, Defining_Entity (N));
      end if;

      --  Make generic parameters immediately visible in the body. They are
      --  needed to process the formals declarations. Then make the formals
      --  visible in a separate step.

      Push_Scope (Gen_Id);

      declare
         E         : Entity_Id;
         First_Ent : Entity_Id;

      begin
         First_Ent := First_Entity (Gen_Id);

         E := First_Ent;
         while Present (E) and then not Is_Formal (E) loop
            Install_Entity (E);
            Next_Entity (E);
         end loop;

         Set_Use (Generic_Formal_Declarations (Gen_Decl));

         --  Now generic formals are visible, and the specification can be
         --  analyzed, for subsequent conformance check.

         Body_Id := Analyze_Subprogram_Specification (Spec);

         --  Make formal parameters visible

         if Present (E) then

            --  E is the first formal parameter, we loop through the formals
            --  installing them so that they will be visible.

            Set_First_Entity (Gen_Id, E);
            while Present (E) loop
               Install_Entity (E);
               Next_Formal (E);
            end loop;
         end if;

         --  Visible generic entity is callable within its own body

         Mutate_Ekind       (Gen_Id,  Ekind (Body_Id));
         Reinit_Field_To_Zero (Body_Id, Has_Out_Or_In_Out_Parameter,
           Old_Ekind =>
             (E_Function | E_Procedure |
                E_Generic_Function | E_Generic_Procedure => True,
              others => False));
         Mutate_Ekind       (Body_Id, E_Subprogram_Body);
         Set_Convention     (Body_Id, Convention (Gen_Id));
         Set_Is_Obsolescent (Body_Id, Is_Obsolescent (Gen_Id));
         Set_Scope          (Body_Id, Scope (Gen_Id));

         Check_Fully_Conformant (Body_Id, Gen_Id, Body_Id);

         if Nkind (N) = N_Subprogram_Body_Stub then

            --  No body to analyze, so restore state of generic unit

            Mutate_Ekind (Gen_Id, Kind);
            Mutate_Ekind (Body_Id, Kind);

            if Present (First_Ent) then
               Set_First_Entity (Gen_Id, First_Ent);
            end if;

            End_Scope;
            return;
         end if;

         --  If this is a compilation unit, it must be made visible explicitly,
         --  because the compilation of the declaration, unlike other library
         --  unit declarations, does not. If it is not a unit, the following
         --  is redundant but harmless.

         Set_Is_Immediately_Visible (Gen_Id);
         Reference_Body_Formals (Gen_Id, Body_Id);

         if Is_Child_Unit (Gen_Id) then
            Generate_Reference (Gen_Id, Scope (Gen_Id), 'k', False);
         end if;

         Set_Actual_Subtypes (N, Current_Scope);

         Set_SPARK_Pragma           (Body_Id, SPARK_Mode_Pragma);
         Set_SPARK_Pragma_Inherited (Body_Id);

         --  Analyze any aspect specifications that appear on the generic
         --  subprogram body.

         if Has_Aspects (N) then
            Analyze_Aspects_On_Subprogram_Body_Or_Stub (N);
         end if;

         Analyze_Declarations (Declarations (N));
         Check_Completion;

         --  Process the contract of the subprogram body after all declarations
         --  have been analyzed. This ensures that any contract-related pragmas
         --  are available through the N_Contract node of the body.

         Analyze_Entry_Or_Subprogram_Body_Contract (Body_Id);

         Analyze (Handled_Statement_Sequence (N));
         Save_Global_References (Original_Node (N));

         --  Prior to exiting the scope, include generic formals again (if any
         --  are present) in the set of local entities.

         if Present (First_Ent) then
            Set_First_Entity (Gen_Id, First_Ent);
         end if;

         Check_References (Gen_Id);
      end;

      Process_End_Label (Handled_Statement_Sequence (N), 't', Current_Scope);
      Update_Use_Clause_Chain;
      Validate_Categorization_Dependency (N, Gen_Id);
      End_Scope;
      Check_Subprogram_Order (N);

      --  Outside of its body, unit is generic again

      Reinit_Field_To_Zero (Gen_Id, Has_Nested_Subprogram,
        Old_Ekind => (E_Function | E_Procedure => True, others => False));
      Mutate_Ekind (Gen_Id, Kind);
      Generate_Reference (Gen_Id, Body_Id, 'b', Set_Ref => False);

      if Style_Check then
         Style.Check_Identifier (Body_Id, Gen_Id);
      end if;

      End_Generic;
   end Analyze_Generic_Subprogram_Body;

   ----------------------------
   -- Analyze_Null_Procedure --
   ----------------------------

   --  WARNING: This routine manages Ghost regions. Return statements must be
   --  replaced by gotos that jump to the end of the routine and restore the
   --  Ghost mode.

   procedure Analyze_Null_Procedure
     (N             : Node_Id;
      Is_Completion : out Boolean)
   is
      Loc  : constant Source_Ptr := Sloc (N);
      Spec : constant Node_Id    := Specification (N);

      Saved_GM   : constant Ghost_Mode_Type := Ghost_Mode;
      Saved_IGR  : constant Node_Id         := Ignored_Ghost_Region;
      Saved_ISMP : constant Boolean         :=
                     Ignore_SPARK_Mode_Pragmas_In_Instance;
      --  Save the Ghost and SPARK mode-related data to restore on exit

      Designator : Entity_Id;
      Form       : Node_Id;
      Null_Body  : Node_Id := Empty;
      Null_Stmt  : Node_Id := Null_Statement (Spec);
      Prev       : Entity_Id;

   begin
      Prev := Current_Entity_In_Scope (Defining_Entity (Spec));

      --  A null procedure is Ghost when it is stand-alone and is subject to
      --  pragma Ghost, or when the corresponding spec is Ghost. Set the mode
      --  now, to ensure that any nodes generated during analysis and expansion
      --  are properly marked as Ghost.

      if Present (Prev) then
         Mark_And_Set_Ghost_Body (N, Prev);
      end if;

      --  Capture the profile of the null procedure before analysis, for
      --  expansion at the freeze point and at each point of call. The body is
      --  used if the procedure has preconditions, or if it is a completion. In
      --  the first case the body is analyzed at the freeze point, in the other
      --  it replaces the null procedure declaration.

      --  For a null procedure that comes from source, a NULL statement is
      --  provided by the parser, which carries the source location of the
      --  NULL keyword, and has Comes_From_Source set. For a null procedure
      --  from expansion, create one now.

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

      Null_Body :=
        Make_Subprogram_Body (Loc,
          Specification              => New_Copy_Tree (Spec),
          Declarations               => New_List,
          Handled_Statement_Sequence =>
            Make_Handled_Sequence_Of_Statements (Loc,
              Statements => New_List (Null_Stmt)));

      --  Create new entities for body and formals

      Set_Defining_Unit_Name (Specification (Null_Body),
        Make_Defining_Identifier
          (Sloc (Defining_Entity (N)),
           Chars (Defining_Entity (N))));

      Form := First (Parameter_Specifications (Specification (Null_Body)));
      while Present (Form) loop
         Set_Defining_Identifier (Form,
           Make_Defining_Identifier
             (Sloc (Defining_Identifier (Form)),
              Chars (Defining_Identifier (Form))));
         Next (Form);
      end loop;

      --  Determine whether the null procedure may be a completion of a generic
      --  suprogram, in which case we use the new null body as the completion
      --  and set minimal semantic information on the original declaration,
      --  which is rewritten as a null statement.

      if Present (Prev) and then Is_Generic_Subprogram (Prev) then
         Insert_Before (N, Null_Body);
         Mutate_Ekind (Defining_Entity (N), Ekind (Prev));

         Rewrite (N, Make_Null_Statement (Loc));
         Analyze_Generic_Subprogram_Body (Null_Body, Prev);
         Is_Completion := True;

         goto Leave;

      else
         --  Resolve the types of the formals now, because the freeze point may
         --  appear in a different context, e.g. an instantiation.

         Form := First (Parameter_Specifications (Specification (Null_Body)));
         while Present (Form) loop
            if Nkind (Parameter_Type (Form)) /= N_Access_Definition then
               Find_Type (Parameter_Type (Form));

            elsif No (Access_To_Subprogram_Definition
                       (Parameter_Type (Form)))
            then
               Find_Type (Subtype_Mark (Parameter_Type (Form)));

            --  The case of a null procedure with a formal that is an
            --  access-to-subprogram type, and that is used as an actual
            --  in an instantiation is left to the enthusiastic reader.

            else
               null;
            end if;

            Next (Form);
         end loop;
      end if;

      --  If there are previous overloadable entities with the same name, check
      --  whether any of them is completed by the null procedure.

      if Present (Prev) and then Is_Overloadable (Prev) then
         Designator := Analyze_Subprogram_Specification (Spec);
         Prev       := Find_Corresponding_Spec (N);
      end if;

      if No (Prev) or else not Comes_From_Source (Prev) then
         Designator := Analyze_Subprogram_Specification (Spec);
         Set_Has_Completion (Designator);

         --  Signal to caller that this is a procedure declaration

         Is_Completion := False;

         --  Null procedures are always inlined, but generic formal subprograms
         --  which appear as such in the internal instance of formal packages,
         --  need no completion and are not marked Inline.

         if Expander_Active
           and then Nkind (N) /= N_Formal_Concrete_Subprogram_Declaration
         then
            Set_Corresponding_Body (N, Defining_Entity (Null_Body));
            Set_Body_To_Inline (N, Null_Body);
            Set_Is_Inlined (Designator);
         end if;

      else
         --  The null procedure is a completion. We unconditionally rewrite
         --  this as a null body (even if expansion is not active), because
         --  there are various error checks that are applied on this body
         --  when it is analyzed (e.g. correct aspect placement).

         if Has_Completion (Prev) then
            Error_Msg_Sloc := Sloc (Prev);
            Error_Msg_NE ("duplicate body for & declared#", N, Prev);
         end if;

         Check_Previous_Null_Procedure (N, Prev);

         Is_Completion := True;
         Rewrite (N, Null_Body);
         Analyze (N);
      end if;

   <<Leave>>
      Ignore_SPARK_Mode_Pragmas_In_Instance := Saved_ISMP;
      Restore_Ghost_Region (Saved_GM, Saved_IGR);
   end Analyze_Null_Procedure;

   -----------------------------
   -- Analyze_Operator_Symbol --
   -----------------------------

   --  An operator symbol such as "+" or "and" may appear in context where the
   --  literal denotes an entity name, such as "+"(x, y) or in context when it
   --  is just a string, as in (conjunction = "or"). In these cases the parser
   --  generates this node, and the semantics does the disambiguation. Other
   --  such case are actuals in an instantiation, the generic unit in an
   --  instantiation, pragma arguments, and aspect specifications.

   procedure Analyze_Operator_Symbol (N : Node_Id) is
      Par : constant Node_Id := Parent (N);

      Maybe_Aspect_Spec : Node_Id := Par;
   begin
      if Nkind (Maybe_Aspect_Spec) /= N_Aspect_Specification then
         --  deal with N_Aggregate nodes
         Maybe_Aspect_Spec := Parent (Maybe_Aspect_Spec);
      end if;

      if        (Nkind (Par) = N_Function_Call and then N = Name (Par))
        or else  Nkind (Par) = N_Function_Instantiation
        or else (Nkind (Par) = N_Indexed_Component and then N = Prefix (Par))
        or else (Nkind (Par) = N_Pragma_Argument_Association
                  and then not Is_Pragma_String_Literal (Par))
        or else  Nkind (Par) = N_Subprogram_Renaming_Declaration
        or else (Nkind (Par) = N_Attribute_Reference
                  and then Attribute_Name (Par) /= Name_Value)
        or else (Nkind (Maybe_Aspect_Spec) = N_Aspect_Specification
                  and then Get_Aspect_Id (Maybe_Aspect_Spec)
                            --  include other aspects here ???
                            in Aspect_Stable_Properties | Aspect_Aggregate)
      then
         Find_Direct_Name (N);

      else
         Change_Operator_Symbol_To_String_Literal (N);
         Analyze (N);
      end if;
   end Analyze_Operator_Symbol;

   -----------------------------------
   -- Analyze_Parameter_Association --
   -----------------------------------

   procedure Analyze_Parameter_Association (N : Node_Id) is
   begin
      Analyze (Explicit_Actual_Parameter (N));
   end Analyze_Parameter_Association;

   ----------------------------
   -- Analyze_Procedure_Call --
   ----------------------------

   --  WARNING: This routine manages Ghost regions. Return statements must be
   --  replaced by gotos that jump to the end of the routine and restore the
   --  Ghost mode.

   procedure Analyze_Procedure_Call (N : Node_Id) is
      procedure Analyze_Call_And_Resolve;
      --  Do Analyze and Resolve calls for procedure call. At the end, check
      --  for illegal order dependence.
      --  ??? where is the check for illegal order dependencies?

      ------------------------------
      -- Analyze_Call_And_Resolve --
      ------------------------------

      procedure Analyze_Call_And_Resolve is
      begin
         if Nkind (N) = N_Procedure_Call_Statement then
            Analyze_Call (N);
            Resolve (N, Standard_Void_Type);
         else
            Analyze (N);
         end if;
      end Analyze_Call_And_Resolve;

      --  Local variables

      Actuals : constant List_Id    := Parameter_Associations (N);
      Loc     : constant Source_Ptr := Sloc (N);
      P       : constant Node_Id    := Name (N);

      Saved_GM  : constant Ghost_Mode_Type := Ghost_Mode;
      Saved_IGR : constant Node_Id         := Ignored_Ghost_Region;
      --  Save the Ghost-related attributes to restore on exit

      Actual : Node_Id;
      New_N  : Node_Id;

   --  Start of processing for Analyze_Procedure_Call

   begin
      --  The syntactic construct: PREFIX ACTUAL_PARAMETER_PART can denote
      --  a procedure call or an entry call. The prefix may denote an access
      --  to subprogram type, in which case an implicit dereference applies.
      --  If the prefix is an indexed component (without implicit dereference)
      --  then the construct denotes a call to a member of an entire family.
      --  If the prefix is a simple name, it may still denote a call to a
      --  parameterless member of an entry family. Resolution of these various
      --  interpretations is delicate.

      --  Do not analyze machine code statements to avoid rejecting them in
      --  CodePeer mode.

      if CodePeer_Mode and then Nkind (P) = N_Qualified_Expression then
         Set_Etype (P, Standard_Void_Type);
      else
         Analyze (P);
      end if;

      --  If this is a call of the form Obj.Op, the call may have been analyzed
      --  and possibly rewritten into a block, in which case we are done.

      if Analyzed (N) then
         return;

      --  If there is an error analyzing the name (which may have been
      --  rewritten if the original call was in prefix notation) then error
      --  has been emitted already, mark node and return.

      elsif Error_Posted (N) or else Etype (Name (N)) = Any_Type then
         Set_Etype (N, Any_Type);
         return;
      end if;

      --  A procedure call is Ghost when its name denotes a Ghost procedure.
      --  Set the mode now to ensure that any nodes generated during analysis
      --  and expansion are properly marked as Ghost.

      Mark_And_Set_Ghost_Procedure_Call (N);

      --  Otherwise analyze the parameters

      if Present (Actuals) then
         Actual := First (Actuals);

         while Present (Actual) loop
            Analyze (Actual);
            Check_Parameterless_Call (Actual);
            Next (Actual);
         end loop;
      end if;

      --  Special processing for Elab_Spec, Elab_Body and Elab_Subp_Body calls

      if Nkind (P) = N_Attribute_Reference
        and then Attribute_Name (P) in Name_Elab_Spec
                                     | Name_Elab_Body
                                     | Name_Elab_Subp_Body
      then
         if Present (Actuals) then
            Error_Msg_N
              ("no parameters allowed for this call", First (Actuals));
            goto Leave;
         end if;

         Set_Etype (N, Standard_Void_Type);
         Set_Analyzed (N);

      elsif Is_Entity_Name (P)
        and then Is_Record_Type (Etype (Entity (P)))
        and then Remote_AST_I_Dereference (P)
      then
         goto Leave;

      elsif Is_Entity_Name (P)
        and then Ekind (Entity (P)) /= E_Entry_Family
      then
         if Is_Access_Type (Etype (P))
           and then Ekind (Designated_Type (Etype (P))) = E_Subprogram_Type
           and then No (Actuals)
           and then Comes_From_Source (N)
         then
            Error_Msg_N ("missing explicit dereference in call", N);

         elsif Ekind (Entity (P)) = E_Operator then
            Error_Msg_Name_1 := Chars (P);
            Error_Msg_N ("operator % cannot be used as a procedure", N);
         end if;

         Analyze_Call_And_Resolve;

      --  If the prefix is the simple name of an entry family, this is a
      --  parameterless call from within the task body itself.

      elsif Is_Entity_Name (P)
        and then Nkind (P) = N_Identifier
        and then Ekind (Entity (P)) = E_Entry_Family
        and then Present (Actuals)
        and then No (Next (First (Actuals)))
      then
         --  Can be call to parameterless entry family. What appears to be the
         --  sole argument is in fact the entry index. Rewrite prefix of node
         --  accordingly. Source representation is unchanged by this
         --  transformation.

         New_N :=
           Make_Indexed_Component (Loc,
             Prefix      =>
               Make_Selected_Component (Loc,
                 Prefix        => New_Occurrence_Of (Scope (Entity (P)), Loc),
                 Selector_Name => New_Occurrence_Of (Entity (P), Loc)),
             Expressions => Actuals);
         Set_Name (N, New_N);
         Set_Etype (New_N, Standard_Void_Type);
         Set_Parameter_Associations (N, No_List);
         Analyze_Call_And_Resolve;

      elsif Nkind (P) = N_Explicit_Dereference then
         if Ekind (Etype (P)) = E_Subprogram_Type then
            Analyze_Call_And_Resolve;
         else
            Error_Msg_N ("expect access to procedure in call", P);
         end if;

      --  The name can be a selected component or an indexed component that
      --  yields an access to subprogram. Such a prefix is legal if the call
      --  has parameter associations.

      elsif Is_Access_Type (Etype (P))
        and then Ekind (Designated_Type (Etype (P))) = E_Subprogram_Type
      then
         if Present (Actuals) then
            Analyze_Call_And_Resolve;
         else
            Error_Msg_N ("missing explicit dereference in call", N);
         end if;

      --  If not an access to subprogram, then the prefix must resolve to the
      --  name of an entry, entry family, or protected operation.

      --  For the case of a simple entry call, P is a selected component where
      --  the prefix is the task and the selector name is the entry. A call to
      --  a protected procedure will have the same syntax. If the protected
      --  object contains overloaded operations, the entity may appear as a
      --  function, the context will select the operation whose type is Void.

      elsif Nkind (P) = N_Selected_Component
        and then Ekind (Entity (Selector_Name (P)))
                   in E_Entry | E_Function | E_Procedure
      then
         --  When front-end inlining is enabled, as with SPARK_Mode, a call
         --  in prefix notation may still be missing its controlling argument,
         --  so perform the transformation now.

         if SPARK_Mode = On and then In_Inlined_Body then
            declare
               Subp : constant Entity_Id := Entity (Selector_Name (P));
               Typ  : constant Entity_Id := Etype (Prefix (P));

            begin
               if Is_Tagged_Type (Typ)
                 and then Present (First_Formal (Subp))
                 and then (Etype (First_Formal (Subp)) = Typ
                             or else
                           Class_Wide_Type (Etype (First_Formal (Subp))) = Typ)
                 and then Try_Object_Operation (P)
               then
                  return;

               else
                  Analyze_Call_And_Resolve;
               end if;
            end;

         else
            Analyze_Call_And_Resolve;
         end if;

      elsif Nkind (P) = N_Selected_Component
        and then Ekind (Entity (Selector_Name (P))) = E_Entry_Family
        and then Present (Actuals)
        and then No (Next (First (Actuals)))
      then
         --  Can be call to parameterless entry family. What appears to be the
         --  sole argument is in fact the entry index. Rewrite prefix of node
         --  accordingly. Source representation is unchanged by this
         --  transformation.

         New_N :=
           Make_Indexed_Component (Loc,
             Prefix      => New_Copy (P),
             Expressions => Actuals);
         Set_Name (N, New_N);
         Set_Etype (New_N, Standard_Void_Type);
         Set_Parameter_Associations (N, No_List);
         Analyze_Call_And_Resolve;

      --  For the case of a reference to an element of an entry family, P is
      --  an indexed component whose prefix is a selected component (task and
      --  entry family), and whose index is the entry family index.

      elsif Nkind (P) = N_Indexed_Component
        and then Nkind (Prefix (P)) = N_Selected_Component
        and then Ekind (Entity (Selector_Name (Prefix (P)))) = E_Entry_Family
      then
         Analyze_Call_And_Resolve;

      --  If the prefix is the name of an entry family, it is a call from
      --  within the task body itself.

      elsif Nkind (P) = N_Indexed_Component
        and then Nkind (Prefix (P)) = N_Identifier
        and then Ekind (Entity (Prefix (P))) = E_Entry_Family
      then
         New_N :=
           Make_Selected_Component (Loc,
             Prefix        =>
               New_Occurrence_Of (Scope (Entity (Prefix (P))), Loc),
             Selector_Name => New_Occurrence_Of (Entity (Prefix (P)), Loc));
         Rewrite (Prefix (P), New_N);
         Analyze (P);
         Analyze_Call_And_Resolve;

      --  In Ada 2012. a qualified expression is a name, but it cannot be a
      --  procedure name, so the construct can only be a qualified expression.

      elsif Nkind (P) = N_Qualified_Expression
        and then Ada_Version >= Ada_2012
      then
         Rewrite (N, Make_Code_Statement (Loc, Expression => P));
         Analyze (N);

      --  Anything else is an error

      else
         Error_Msg_N ("invalid procedure or entry call", N);

         --  Specialize the error message in the case where both a primitive
         --  operation and a record component are visible at the same time.

         if Nkind (P) = N_Selected_Component
           and then Is_Entity_Name (Selector_Name (P))
         then
            declare
               Sel : constant Entity_Id := Entity (Selector_Name (P));
            begin
               if Ekind (Sel) = E_Component
                 and then Present (Homonym (Sel))
                 and then Ekind (Homonym (Sel)) = E_Procedure
               then
                  Error_Msg_NE ("\component & conflicts with"
                    & " homonym procedure (RM 4.1.3 (9.2/3))",
                    Selector_Name (P), Sel);
               end if;
            end;
         end if;
      end if;

   <<Leave>>
      Restore_Ghost_Region (Saved_GM, Saved_IGR);
   end Analyze_Procedure_Call;

   ------------------------------
   -- Analyze_Return_Statement --
   ------------------------------

   procedure Analyze_Return_Statement (N : Node_Id) is
      pragma Assert
        (Nkind (N) in N_Extended_Return_Statement | N_Simple_Return_Statement);

      Returns_Object : constant Boolean :=
                         Nkind (N) = N_Extended_Return_Statement
                           or else
                             (Nkind (N) = N_Simple_Return_Statement
                               and then Present (Expression (N)));
      --  True if we're returning something; that is, "return <expression>;"
      --  or "return Result : T [:= ...]". False for "return;". Used for error
      --  checking: If Returns_Object is True, N should apply to a function
      --  body; otherwise N should apply to a procedure body, entry body,
      --  accept statement, or extended return statement.

      function Find_What_It_Applies_To return Entity_Id;
      --  Find the entity representing the innermost enclosing body, accept
      --  statement, or extended return statement. If the result is a callable
      --  construct or extended return statement, then this will be the value
      --  of the Return_Applies_To attribute. Otherwise, the program is
      --  illegal. See RM-6.5(4/2).

      -----------------------------
      -- Find_What_It_Applies_To --
      -----------------------------

      function Find_What_It_Applies_To return Entity_Id is
         Result : Entity_Id := Empty;

      begin
         --  Loop outward through the Scope_Stack, skipping blocks, and loops

         for J in reverse 0 .. Scope_Stack.Last loop
            Result := Scope_Stack.Table (J).Entity;
            exit when Ekind (Result) not in E_Block | E_Loop;
         end loop;

         pragma Assert (Present (Result));
         return Result;
      end Find_What_It_Applies_To;

      --  Local declarations

      Scope_Id   : constant Entity_Id   := Find_What_It_Applies_To;
      Kind       : constant Entity_Kind := Ekind (Scope_Id);
      Loc        : constant Source_Ptr  := Sloc (N);
      Stm_Entity : constant Entity_Id   :=
                     New_Internal_Entity
                       (E_Return_Statement, Current_Scope, Loc, 'R');

   --  Start of processing for Analyze_Return_Statement

   begin
      Set_Return_Statement_Entity (N, Stm_Entity);

      Set_Etype (Stm_Entity, Standard_Void_Type);
      Set_Return_Applies_To (Stm_Entity, Scope_Id);

      --  Place Return entity on scope stack, to simplify enforcement of 6.5
      --  (4/2): an inner return statement will apply to this extended return.

      if Nkind (N) = N_Extended_Return_Statement then
         Push_Scope (Stm_Entity);
      end if;

      --  Check that pragma No_Return is obeyed. Don't complain about the
      --  implicitly-generated return that is placed at the end.

      if No_Return (Scope_Id)
        and then Kind in E_Procedure | E_Generic_Procedure
        and then Comes_From_Source (N)
      then
         Error_Msg_N
           ("RETURN statement not allowed in No_Return procedure", N);
      end if;

      --  Warn on any unassigned OUT parameters if in procedure

      if Ekind (Scope_Id) = E_Procedure then
         Warn_On_Unassigned_Out_Parameter (N, Scope_Id);
      end if;

      --  Check that functions return objects, and other things do not

      if Kind in E_Function | E_Generic_Function then
         if not Returns_Object then
            Error_Msg_N ("missing expression in return from function", N);
         end if;

      elsif Kind in E_Procedure | E_Generic_Procedure then
         if Returns_Object then
            Error_Msg_N ("procedure cannot return value (use function)", N);
         end if;

      elsif Kind in E_Entry | E_Entry_Family then
         if Returns_Object then
            if Is_Protected_Type (Scope (Scope_Id)) then
               Error_Msg_N ("entry body cannot return value", N);
            else
               Error_Msg_N ("accept statement cannot return value", N);
            end if;
         end if;

      elsif Kind = E_Return_Statement then

         --  We are nested within another return statement, which must be an
         --  extended_return_statement.

         if Returns_Object then
            if Nkind (N) = N_Extended_Return_Statement then
               Error_Msg_N
                 ("extended return statement cannot be nested (use `RETURN;`)",
                  N);

            --  Case of a simple return statement with a value inside extended
            --  return statement.

            else
               Error_Msg_N
                 ("return nested in extended return statement cannot return "
                  & "value (use `RETURN;`)", N);
            end if;
         end if;

      else
         Error_Msg_N ("illegal context for return statement", N);
      end if;

      if Kind in E_Function | E_Generic_Function then
         Analyze_Function_Return (N);

      elsif Kind in E_Procedure | E_Generic_Procedure then
         Set_Return_Present (Scope_Id);
      end if;

      if Nkind (N) = N_Extended_Return_Statement then
         End_Scope;
      end if;

      Kill_Current_Values (Last_Assignment_Only => True);
      Check_Unreachable_Code (N);

      Analyze_Dimension (N);
   end Analyze_Return_Statement;

   -------------------------------------
   -- Analyze_Simple_Return_Statement --
   -------------------------------------

   procedure Analyze_Simple_Return_Statement (N : Node_Id) is
   begin
      if Present (Expression (N)) then
         Mark_Coextensions (N, Expression (N));
      end if;

      Analyze_Return_Statement (N);
   end Analyze_Simple_Return_Statement;

   -------------------------
   -- Analyze_Return_Type --
   -------------------------

   procedure Analyze_Return_Type (N : Node_Id) is
      Designator : constant Entity_Id := Defining_Entity (N);
      Typ        : Entity_Id := Empty;

   begin
      --  Normal case where result definition does not indicate an error

      if Result_Definition (N) /= Error then
         if Nkind (Result_Definition (N)) = N_Access_Definition then

            --  Ada 2005 (AI-254): Handle anonymous access to subprograms

            declare
               AD : constant Node_Id :=
                      Access_To_Subprogram_Definition (Result_Definition (N));
            begin
               if Present (AD) and then Protected_Present (AD) then
                  Typ := Replace_Anonymous_Access_To_Protected_Subprogram (N);
               else
                  Typ := Access_Definition (N, Result_Definition (N));
               end if;
            end;

            Set_Parent (Typ, Result_Definition (N));
            Set_Is_Local_Anonymous_Access (Typ);
            Set_Etype (Designator, Typ);

            --  Ada 2005 (AI-231): Ensure proper usage of null exclusion

            Null_Exclusion_Static_Checks (N);

         --  Subtype_Mark case

         else
            Find_Type (Result_Definition (N));
            Typ := Entity (Result_Definition (N));
            Set_Etype (Designator, Typ);

            --  Ada 2005 (AI-231): Ensure proper usage of null exclusion

            Null_Exclusion_Static_Checks (N);

            --  If a null exclusion is imposed on the result type, then create
            --  a null-excluding itype (an access subtype) and use it as the
            --  function's Etype. Note that the null exclusion checks are done
            --  right before this, because they don't get applied to types that
            --  do not come from source.

            if Is_Access_Type (Typ) and then Null_Exclusion_Present (N) then
               Set_Etype  (Designator,
                 Create_Null_Excluding_Itype
                  (T           => Typ,
                   Related_Nod => N,
                   Scope_Id    => Scope (Current_Scope)));

               --  The new subtype must be elaborated before use because
               --  it is visible outside of the function. However its base
               --  type may not be frozen yet, so the reference that will
               --  force elaboration must be attached to the freezing of
               --  the base type.

               --  If the return specification appears on a proper body,
               --  the subtype will have been created already on the spec.

               if Is_Frozen (Typ) then
                  if Nkind (Parent (N)) = N_Subprogram_Body
                    and then Nkind (Parent (Parent (N))) = N_Subunit
                  then
                     null;
                  else
                     Build_Itype_Reference (Etype (Designator), Parent (N));
                  end if;

               else
                  Ensure_Freeze_Node (Typ);

                  declare
                     IR : constant Node_Id := Make_Itype_Reference (Sloc (N));
                  begin
                     Set_Itype (IR, Etype (Designator));
                     Append_Freeze_Actions (Typ, New_List (IR));
                  end;
               end if;

            else
               Set_Etype (Designator, Typ);
            end if;

            if Ekind (Typ) = E_Incomplete_Type
              or else (Is_Class_Wide_Type (Typ)
                        and then Ekind (Root_Type (Typ)) = E_Incomplete_Type)
            then
               --  AI05-0151: Tagged incomplete types are allowed in all formal
               --  parts. Untagged incomplete types are not allowed in bodies.
               --  As a consequence, limited views cannot appear in a basic
               --  declaration that is itself within a body, because there is
               --  no point at which the non-limited view will become visible.

               if Ada_Version >= Ada_2012 then
                  if From_Limited_With (Typ) and then In_Package_Body then
                     Error_Msg_NE
                       ("invalid use of incomplete type&",
                        Result_Definition (N), Typ);

                  --  The return type of a subprogram body cannot be of a
                  --  formal incomplete type.

                  elsif Is_Generic_Type (Typ)
                    and then Nkind (Parent (N)) = N_Subprogram_Body
                  then
                     Error_Msg_N
                      ("return type cannot be a formal incomplete type",
                        Result_Definition (N));

                  elsif Is_Class_Wide_Type (Typ)
                    and then Is_Generic_Type (Root_Type (Typ))
                    and then Nkind (Parent (N)) = N_Subprogram_Body
                  then
                     Error_Msg_N
                      ("return type cannot be a formal incomplete type",
                        Result_Definition (N));

                  elsif Is_Tagged_Type (Typ) then
                     null;

                  --  Use is legal in a thunk generated for an operation
                  --  inherited from a progenitor.

                  elsif Is_Thunk (Designator)
                    and then Present (Non_Limited_View (Typ))
                  then
                     null;

                  elsif Nkind (Parent (N)) = N_Subprogram_Body
                    or else Nkind (Parent (Parent (N))) in
                              N_Accept_Statement | N_Entry_Body
                  then
                     Error_Msg_NE
                       ("invalid use of untagged incomplete type&",
                          Designator, Typ);
                  end if;

                  --  The type must be completed in the current package. This
                  --  is checked at the end of the package declaration when
                  --  Taft-amendment types are identified. If the return type
                  --  is class-wide, there is no required check, the type can
                  --  be a bona fide TAT.

                  if Ekind (Scope (Current_Scope)) = E_Package
                    and then In_Private_Part (Scope (Current_Scope))
                    and then not Is_Class_Wide_Type (Typ)
                  then
                     Append_Elmt (Designator, Private_Dependents (Typ));
                  end if;

               else
                  Error_Msg_NE
                    ("invalid use of incomplete type&", Designator, Typ);
               end if;
            end if;
         end if;

      --  Case where result definition does indicate an error

      else
         Set_Etype (Designator, Any_Type);
      end if;
   end Analyze_Return_Type;

   -----------------------------
   -- Analyze_Subprogram_Body --
   -----------------------------

   procedure Analyze_Subprogram_Body (N : Node_Id) is
      Loc       : constant Source_Ptr := Sloc (N);
      Body_Spec : constant Node_Id    := Specification (N);
      Body_Id   : constant Entity_Id  := Defining_Entity (Body_Spec);

   begin
      if Debug_Flag_C then
         Write_Str ("==> subprogram body ");
         Write_Name (Chars (Body_Id));
         Write_Str (" from ");
         Write_Location (Loc);
         Write_Eol;
         Indent;
      end if;

      Trace_Scope (N, Body_Id, " Analyze subprogram: ");

      --  The real work is split out into the helper, so it can do "return;"
      --  without skipping the debug output:

      Analyze_Subprogram_Body_Helper (N);

      if Debug_Flag_C then
         Outdent;
         Write_Str ("<== subprogram body ");
         Write_Name (Chars (Body_Id));
         Write_Str (" from ");
         Write_Location (Loc);
         Write_Eol;
      end if;
   end Analyze_Subprogram_Body;

   ------------------------------------
   -- Analyze_Subprogram_Body_Helper --
   ------------------------------------

   --  This procedure is called for regular subprogram bodies, generic bodies,
   --  and for subprogram stubs of both kinds. In the case of stubs, only the
   --  specification matters, and is used to create a proper declaration for
   --  the subprogram, or to perform conformance checks.

   --  WARNING: This routine manages Ghost regions. Return statements must be
   --  replaced by gotos that jump to the end of the routine and restore the
   --  Ghost mode.

   procedure Analyze_Subprogram_Body_Helper (N : Node_Id) is
      Body_Spec : Node_Id             := Specification (N);
      Body_Id   : Entity_Id           := Defining_Entity (Body_Spec);
      Loc       : constant Source_Ptr := Sloc (N);
      Prev_Id   : constant Entity_Id  := Current_Entity_In_Scope (Body_Id);

      Body_Nod         : Node_Id := Empty;
      Minimum_Acc_Objs : List_Id := No_List;

      Conformant : Boolean;
      Desig_View : Entity_Id := Empty;
      Exch_Views : Elist_Id  := No_Elist;
      HSS        : Node_Id;
      Mask_Types : Elist_Id  := No_Elist;
      Prot_Typ   : Entity_Id := Empty;
      Spec_Decl  : Node_Id   := Empty;
      Spec_Id    : Entity_Id;

      Last_Real_Spec_Entity : Entity_Id := Empty;
      --  When we analyze a separate spec, the entity chain ends up containing
      --  the formals, as well as any itypes generated during analysis of the
      --  default expressions for parameters, or the arguments of associated
      --  precondition/postcondition pragmas (which are analyzed in the context
      --  of the spec since they have visibility on formals).
      --
      --  These entities belong with the spec and not the body. However we do
      --  the analysis of the body in the context of the spec (again to obtain
      --  visibility to the formals), and all the entities generated during
      --  this analysis end up also chained to the entity chain of the spec.
      --  But they really belong to the body, and there is circuitry to move
      --  them from the spec to the body.
      --
      --  However, when we do this move, we don't want to move the real spec
      --  entities (first para above) to the body. The Last_Real_Spec_Entity
      --  variable points to the last real spec entity, so we only move those
      --  chained beyond that point. It is initialized to Empty to deal with
      --  the case where there is no separate spec.

      function Body_Has_Contract return Boolean;
      --  Check whether unanalyzed body has an aspect or pragma that may
      --  generate a SPARK contract.

      function Body_Has_SPARK_Mode_On return Boolean;
      --  Check whether SPARK_Mode On applies to the subprogram body, either
      --  because it is specified directly on the body, or because it is
      --  inherited from the enclosing subprogram or package.

      function Build_Internal_Protected_Declaration
        (N : Node_Id) return Entity_Id;
      --  A subprogram body without a previous spec that appears in a protected
      --  body must be expanded separately to create a subprogram declaration
      --  for it, in order to resolve internal calls to it from other protected
      --  operations.
      --
      --  Possibly factor this with Exp_Dist.Copy_Specification ???

      procedure Build_Subprogram_Declaration;
      --  Create a matching subprogram declaration for subprogram body N

      procedure Check_Anonymous_Return;
      --  Ada 2005: if a function returns an access type that denotes a task,
      --  or a type that contains tasks, we must create a master entity for
      --  the anonymous type, which typically will be used in an allocator
      --  in the body of the function.

      procedure Check_Inline_Pragma (Spec : in out Node_Id);
      --  Look ahead to recognize a pragma that may appear after the body.
      --  If there is a previous spec, check that it appears in the same
      --  declarative part. If the pragma is Inline_Always, perform inlining
      --  unconditionally, otherwise only if Front_End_Inlining is requested.
      --  If the body acts as a spec, and inlining is required, we create a
      --  subprogram declaration for it, in order to attach the body to inline.
      --  If pragma does not appear after the body, check whether there is
      --  an inline pragma before any local declarations.

      procedure Check_Missing_Return;
      --  Checks for a function with a no return statements, and also performs
      --  the warning checks implemented by Check_Returns. In formal mode, also
      --  verify that a function ends with a RETURN and that a procedure does
      --  not contain any RETURN.

      function Disambiguate_Spec return Entity_Id;
      --  When a primitive is declared between the private view and the full
      --  view of a concurrent type which implements an interface, a special
      --  mechanism is used to find the corresponding spec of the primitive
      --  body.

      function Exchange_Limited_Views (Subp_Id : Entity_Id) return Elist_Id;
      --  Ada 2012 (AI05-0151): Detect whether the profile of Subp_Id contains
      --  incomplete types coming from a limited context and replace their
      --  limited views with the non-limited ones. Return the list of changes
      --  to be used to undo the transformation.

      procedure Generate_Minimum_Accessibility
        (Extra_Access : Entity_Id;
         Related_Form : Entity_Id := Empty);
      --  Generate a minimum accessibility object for a given extra
      --  accessibility formal (Extra_Access) and its related formal if it
      --  exists.

      function Is_Private_Concurrent_Primitive
        (Subp_Id : Entity_Id) return Boolean;
      --  Determine whether subprogram Subp_Id is a primitive of a concurrent
      --  type that implements an interface and has a private view.

      function Mask_Unfrozen_Types (Spec_Id : Entity_Id) return Elist_Id;
      --  N is the body generated for an expression function that is not a
      --  completion and Spec_Id the defining entity of its spec. Mark all
      --  the not-yet-frozen types referenced by the simple return statement
      --  of the function as formally frozen.

      procedure Move_Pragmas (From : Node_Id; To : Node_Id);
      --  Find all suitable source pragmas at the top of subprogram body
      --  From's declarations and move them after arbitrary node To.
      --  One exception is pragma SPARK_Mode which is copied rather than moved,
      --  as it applies to the body too.

      procedure Restore_Limited_Views (Restore_List : Elist_Id);
      --  Undo the transformation done by Exchange_Limited_Views.

      procedure Set_Trivial_Subprogram (N : Node_Id);
      --  Sets the Is_Trivial_Subprogram flag in both spec and body of the
      --  subprogram whose body is being analyzed. N is the statement node
      --  causing the flag to be set, if the following statement is a return
      --  of an entity, we mark the entity as set in source to suppress any
      --  warning on the stylized use of function stubs with a dummy return.

      procedure Unmask_Unfrozen_Types (Unmask_List : Elist_Id);
      --  Undo the transformation done by Mask_Unfrozen_Types

      procedure Verify_Overriding_Indicator;
      --  If there was a previous spec, the entity has been entered in the
      --  current scope previously. If the body itself carries an overriding
      --  indicator, check that it is consistent with the known status of the
      --  entity.

      -----------------------
      -- Body_Has_Contract --
      -----------------------

      function Body_Has_Contract return Boolean is
         Decls : constant List_Id := Declarations (N);
         Item  : Node_Id;

      begin
         --  Check for aspects that may generate a contract

         if Present (Aspect_Specifications (N)) then
            Item := First (Aspect_Specifications (N));
            while Present (Item) loop
               if Is_Subprogram_Contract_Annotation (Item) then
                  return True;
               end if;

               Next (Item);
            end loop;
         end if;

         --  Check for pragmas that may generate a contract

         if Present (Decls) then
            Item := First (Decls);
            while Present (Item) loop
               if Nkind (Item) = N_Pragma
                 and then Is_Subprogram_Contract_Annotation (Item)
               then
                  return True;
               end if;

               Next (Item);
            end loop;
         end if;

         return False;
      end Body_Has_Contract;

      ----------------------------
      -- Body_Has_SPARK_Mode_On --
      ----------------------------

      function Body_Has_SPARK_Mode_On return Boolean is
         Decls : constant List_Id := Declarations (N);
         Item  : Node_Id;

      begin
         --  Check for SPARK_Mode aspect

         if Present (Aspect_Specifications (N)) then
            Item := First (Aspect_Specifications (N));
            while Present (Item) loop
               if Get_Aspect_Id (Item) = Aspect_SPARK_Mode then
                  return Get_SPARK_Mode_From_Annotation (Item) = On;
               end if;

               Next (Item);
            end loop;
         end if;

         --  Check for SPARK_Mode pragma

         if Present (Decls) then
            Item := First (Decls);
            while Present (Item) loop

               --  Pragmas that apply to a subprogram body are usually grouped
               --  together. Look for a potential pragma SPARK_Mode among them.

               if Nkind (Item) = N_Pragma then
                  if Get_Pragma_Id (Item) = Pragma_SPARK_Mode then
                     return Get_SPARK_Mode_From_Annotation (Item) = On;
                  end if;

               --  Otherwise the first non-pragma declarative item terminates
               --  the region where pragma SPARK_Mode may appear.

               else
                  exit;
               end if;

               Next (Item);
            end loop;
         end if;

         --  Otherwise, the applicable SPARK_Mode is inherited from the
         --  enclosing subprogram or package.

         return SPARK_Mode = On;
      end Body_Has_SPARK_Mode_On;

      ------------------------------------------
      -- Build_Internal_Protected_Declaration --
      ------------------------------------------

      function Build_Internal_Protected_Declaration
        (N : Node_Id) return Entity_Id
      is
         procedure Analyze_Pragmas (From : Node_Id);
         --  Analyze all pragmas which follow arbitrary node From

         ---------------------
         -- Analyze_Pragmas --
         ---------------------

         procedure Analyze_Pragmas (From : Node_Id) is
            Decl : Node_Id;

         begin
            Decl := Next (From);
            while Present (Decl) loop
               if Nkind (Decl) = N_Pragma then
                  Analyze_Pragma (Decl);

               --  No candidate pragmas are available for analysis

               else
                  exit;
               end if;

               Next (Decl);
            end loop;
         end Analyze_Pragmas;

         --  Local variables

         Body_Id  : constant Entity_Id  := Defining_Entity (N);
         Loc      : constant Source_Ptr := Sloc (N);
         Decl     : Node_Id;
         Formal   : Entity_Id;
         Formals  : List_Id;
         Spec     : Node_Id;
         Spec_Id  : Entity_Id;

      --  Start of processing for Build_Internal_Protected_Declaration

      begin
         Formal := First_Formal (Body_Id);

         --  The protected operation always has at least one formal, namely the
         --  object itself, but it is only placed in the parameter list if
         --  expansion is enabled.

         if Present (Formal) or else Expander_Active then
            Formals := Copy_Parameter_List (Body_Id);
         else
            Formals := No_List;
         end if;

         Spec_Id :=
           Make_Defining_Identifier (Sloc (Body_Id),
             Chars => Chars (Body_Id));

         --  Indicate that the entity comes from source, to ensure that cross-
         --  reference information is properly generated. The body itself is
         --  rewritten during expansion, and the body entity will not appear in
         --  calls to the operation.

         Set_Comes_From_Source (Spec_Id, True);

         if Nkind (Specification (N)) = N_Procedure_Specification then
            Spec :=
              Make_Procedure_Specification (Loc,
                 Defining_Unit_Name       => Spec_Id,
                 Parameter_Specifications => Formals);
         else
            Spec :=
              Make_Function_Specification (Loc,
                Defining_Unit_Name       => Spec_Id,
                Parameter_Specifications => Formals,
                Result_Definition        =>
                  New_Occurrence_Of (Etype (Body_Id), Loc));
         end if;

         Decl := Make_Subprogram_Declaration (Loc, Specification => Spec);
         Set_Corresponding_Body (Decl, Body_Id);
         Set_Corresponding_Spec (N,    Spec_Id);

         Insert_Before (N, Decl);

         --  Associate all aspects and pragmas of the body with the spec. This
         --  ensures that these annotations apply to the initial declaration of
         --  the subprogram body.

         Move_Aspects (From => N, To => Decl);
         Move_Pragmas (From => N, To => Decl);

         Analyze (Decl);

         --  The analysis of the spec may generate pragmas which require manual
         --  analysis. Since the generation of the spec and the relocation of
         --  the annotations is driven by the expansion of the stand-alone
         --  body, the pragmas will not be analyzed in a timely manner. Do this
         --  now.

         Analyze_Pragmas (Decl);

         --  This subprogram has convention Intrinsic as per RM 6.3.1(10/2)
         --  ensuring in particular that 'Access is illegal.

         Set_Convention     (Spec_Id, Convention_Intrinsic);
         Set_Has_Completion (Spec_Id);

         return Spec_Id;
      end Build_Internal_Protected_Declaration;

      ----------------------------------
      -- Build_Subprogram_Declaration --
      ----------------------------------

      procedure Build_Subprogram_Declaration is
         Decl      : Node_Id;
         Subp_Decl : Node_Id;

      begin
         --  Create a matching subprogram spec using the profile of the body.
         --  The structure of the tree is identical, but has new entities for
         --  the defining unit name and formal parameters.

         Subp_Decl :=
           Make_Subprogram_Declaration (Loc,
             Specification => Copy_Subprogram_Spec (Body_Spec));
         Set_Comes_From_Source (Subp_Decl, True);

         --  Also mark parameters as coming from source

         if Present (Parameter_Specifications (Specification (Subp_Decl))) then
            declare
               Form : Entity_Id;
            begin
               Form :=
                 First (Parameter_Specifications (Specification (Subp_Decl)));

               while Present (Form) loop
                  Set_Comes_From_Source (Defining_Identifier (Form), True);
                  Next (Form);
               end loop;
            end;
         end if;

         --  Relocate the aspects and relevant pragmas from the subprogram body
         --  to the generated spec because it acts as the initial declaration.

         Insert_Before (N, Subp_Decl);
         Move_Aspects (N, To => Subp_Decl);
         Move_Pragmas (N, To => Subp_Decl);

         --  Ensure that the generated corresponding spec and original body
         --  share the same SPARK_Mode pragma or aspect. As a result, both have
         --  the same SPARK_Mode attributes, and the global SPARK_Mode value is
         --  correctly set for local subprograms.

         Copy_SPARK_Mode_Aspect (Subp_Decl, To => N);

         Analyze (Subp_Decl);

         --  Propagate the attributes Rewritten_For_C and Corresponding_Proc to
         --  the body since the expander may generate calls using that entity.
         --  Required to ensure that Expand_Call rewrites calls to this
         --  function by calls to the built procedure.

         if Transform_Function_Array
           and then Nkind (Body_Spec) = N_Function_Specification
           and then
             Rewritten_For_C (Defining_Entity (Specification (Subp_Decl)))
         then
            Set_Rewritten_For_C (Defining_Entity (Body_Spec));
            Set_Corresponding_Procedure (Defining_Entity (Body_Spec),
              Corresponding_Procedure
                (Defining_Entity (Specification (Subp_Decl))));
         end if;

         --  Analyze any relocated source pragmas or pragmas created for aspect
         --  specifications.

         Decl := Next (Subp_Decl);
         while Present (Decl) loop

            --  Stop the search for pragmas once the body has been reached as
            --  this terminates the region where pragmas may appear.

            if Decl = N then
               exit;

            elsif Nkind (Decl) = N_Pragma then
               Analyze (Decl);
            end if;

            Next (Decl);
         end loop;

         Spec_Id := Defining_Entity (Subp_Decl);
         Set_Corresponding_Spec (N, Spec_Id);

         --  Mark the generated spec as a source construct to ensure that all
         --  calls to it are properly registered in ALI files for GNATprove.

         Set_Comes_From_Source (Spec_Id, True);

         --  Ensure that the specs of the subprogram declaration and its body
         --  are identical, otherwise they will appear non-conformant due to
         --  rewritings in the default values of formal parameters.

         Body_Spec := Copy_Subprogram_Spec (Body_Spec);
         Set_Specification (N, Body_Spec);
         Body_Id := Analyze_Subprogram_Specification (Body_Spec);
      end Build_Subprogram_Declaration;

      ----------------------------
      -- Check_Anonymous_Return --
      ----------------------------

      procedure Check_Anonymous_Return is
         Decl : Node_Id;
         Par  : Node_Id;
         Scop : Entity_Id;

      begin
         if Present (Spec_Id) then
            Scop := Spec_Id;
         else
            Scop := Body_Id;
         end if;

         if Ekind (Scop) = E_Function
           and then Ekind (Etype (Scop)) = E_Anonymous_Access_Type
           and then not Is_Thunk (Scop)

            --  Skip internally built functions which handle the case of
            --  a null access (see Expand_Interface_Conversion)

           and then not (Is_Interface (Designated_Type (Etype (Scop)))
                          and then not Comes_From_Source (Parent (Scop)))

           and then (Has_Task (Designated_Type (Etype (Scop)))
                      or else
                        (Is_Class_Wide_Type (Designated_Type (Etype (Scop)))
                           and then
                         Is_Limited_Record (Designated_Type (Etype (Scop)))))
           and then Expander_Active
         then
            Decl := Build_Master_Declaration (Loc);

            if Present (Declarations (N)) then
               Prepend (Decl, Declarations (N));
            else
               Set_Declarations (N, New_List (Decl));
            end if;

            Set_Master_Id (Etype (Scop), Defining_Identifier (Decl));
            Set_Has_Master_Entity (Scop);

            --  Now mark the containing scope as a task master

            Par := N;
            while Nkind (Par) /= N_Compilation_Unit loop
               Par := Parent (Par);
               pragma Assert (Present (Par));

               --  If we fall off the top, we are at the outer level, and
               --  the environment task is our effective master, so nothing
               --  to mark.

               if Nkind (Par)
                    in N_Task_Body | N_Block_Statement | N_Subprogram_Body
               then
                  Set_Is_Task_Master (Par, True);
                  exit;
               end if;
            end loop;
         end if;
      end Check_Anonymous_Return;

      -------------------------
      -- Check_Inline_Pragma --
      -------------------------

      procedure Check_Inline_Pragma (Spec : in out Node_Id) is
         Prag  : Node_Id;
         Plist : List_Id;

         function Is_Inline_Pragma (N : Node_Id) return Boolean;
         --  True when N is a pragma Inline or Inline_Always that applies
         --  to this subprogram.

         -----------------------
         --  Is_Inline_Pragma --
         -----------------------

         function Is_Inline_Pragma (N : Node_Id) return Boolean is
         begin
            if Nkind (N) = N_Pragma
                and then
                  (Pragma_Name_Unmapped (N) = Name_Inline_Always
                    or else (Pragma_Name_Unmapped (N) = Name_Inline
                      and then
                        (Front_End_Inlining or else Optimization_Level > 0)))
               and then Present (Pragma_Argument_Associations (N))
            then
               declare
                  Pragma_Arg : Node_Id :=
                    Expression (First (Pragma_Argument_Associations (N)));
               begin
                  if Nkind (Pragma_Arg) = N_Selected_Component then
                     Pragma_Arg := Selector_Name (Pragma_Arg);
                  end if;

                  return Chars (Pragma_Arg) = Chars (Body_Id);
               end;

            else
               return False;
            end if;
         end Is_Inline_Pragma;

      --  Start of processing for Check_Inline_Pragma

      begin
         if not Expander_Active then
            return;
         end if;

         if Is_List_Member (N)
           and then Present (Next (N))
           and then Is_Inline_Pragma (Next (N))
         then
            Prag := Next (N);

         elsif Nkind (N) /= N_Subprogram_Body_Stub
           and then Present (Declarations (N))
           and then Is_Inline_Pragma (First (Declarations (N)))
         then
            Prag := First (Declarations (N));

         else
            Prag := Empty;
         end if;

         if Present (Prag) and then Is_List_Member (N) then
            if Present (Spec_Id) then
               if Is_List_Member (Unit_Declaration_Node (Spec_Id))
                 and then In_Same_List (N, Unit_Declaration_Node (Spec_Id))
               then
                  Analyze (Prag);
               end if;
            else
               --  Create a subprogram declaration, to make treatment uniform.
               --  Make the sloc of the subprogram name that of the entity in
               --  the body, so that style checks find identical strings.

               declare
                  Subp : constant Entity_Id :=
                           Make_Defining_Identifier
                             (Sloc (Body_Id), Chars (Body_Id));
                  Decl : constant Node_Id :=
                           Make_Subprogram_Declaration (Loc,
                             Specification =>
                               New_Copy_Tree (Specification (N)));

               begin
                  --  Link the body and the generated spec

                  Set_Corresponding_Body (Decl, Body_Id);
                  Set_Corresponding_Spec (N, Subp);

                  Set_Defining_Unit_Name (Specification (Decl), Subp);

                  --  To ensure proper coverage when body is inlined, indicate
                  --  whether the subprogram comes from source.

                  Preserve_Comes_From_Source (Subp, N);

                  if Present (First_Formal (Body_Id)) then
                     Plist := Copy_Parameter_List (Body_Id);
                     Set_Parameter_Specifications
                       (Specification (Decl), Plist);
                  end if;

                  --  Move aspects to the new spec

                  if Has_Aspects (N) then
                     Move_Aspects (N, To => Decl);
                  end if;

                  Insert_Before (N, Decl);
                  Analyze (Decl);
                  Analyze (Prag);
                  Set_Has_Pragma_Inline (Subp);

                  if Pragma_Name (Prag) = Name_Inline_Always then
                     Set_Is_Inlined (Subp);
                     Set_Has_Pragma_Inline_Always (Subp);
                  end if;

                  --  Prior to copying the subprogram body to create a template
                  --  for it for subsequent inlining, remove the pragma from
                  --  the current body so that the copy that will produce the
                  --  new body will start from a completely unanalyzed tree.

                  if Nkind (Parent (Prag)) = N_Subprogram_Body then
                     Rewrite (Prag, Make_Null_Statement (Sloc (Prag)));
                  end if;

                  Spec := Subp;
               end;
            end if;
         end if;
      end Check_Inline_Pragma;

      --------------------------
      -- Check_Missing_Return --
      --------------------------

      procedure Check_Missing_Return is
         Id          : Entity_Id;
         Missing_Ret : Boolean;

      begin
         if Nkind (Body_Spec) = N_Function_Specification then
            if Present (Spec_Id) then
               Id := Spec_Id;
            else
               Id := Body_Id;
            end if;

            if Return_Present (Id) then
               Check_Returns (HSS, 'F', Missing_Ret);

               if Missing_Ret then
                  Set_Has_Missing_Return (Id);
               end if;

            --  Within a premature instantiation of a package with no body, we
            --  build completions of the functions therein, with a Raise
            --  statement. No point in complaining about a missing return in
            --  this case.

            elsif Ekind (Id) = E_Function
              and then In_Instance
              and then Present (Statements (HSS))
              and then Nkind (First (Statements (HSS))) = N_Raise_Program_Error
            then
               null;

            elsif Is_Generic_Subprogram (Id)
              or else not Is_Machine_Code_Subprogram (Id)
            then
               Error_Msg_N ("missing RETURN statement in function body", N);
            end if;

         --  If procedure with No_Return, check returns

         elsif Nkind (Body_Spec) = N_Procedure_Specification then
            if Present (Spec_Id) then
               Id := Spec_Id;
            else
               Id := Body_Id;
            end if;

            if No_Return (Id) then
               Check_Returns (HSS, 'P', Missing_Ret, Id);
            end if;
         end if;
      end Check_Missing_Return;

      -----------------------
      -- Disambiguate_Spec --
      -----------------------

      function Disambiguate_Spec return Entity_Id is
         Priv_Spec : Entity_Id;
         Spec_N    : Entity_Id;

         procedure Replace_Types (To_Corresponding : Boolean);
         --  Depending on the flag, replace the type of formal parameters of
         --  Body_Id if it is a concurrent type implementing interfaces with
         --  the corresponding record type or the other way around.

         procedure Replace_Types (To_Corresponding : Boolean) is
            Formal     : Entity_Id;
            Formal_Typ : Entity_Id;

         begin
            Formal := First_Formal (Body_Id);
            while Present (Formal) loop
               Formal_Typ := Etype (Formal);

               if Is_Class_Wide_Type (Formal_Typ) then
                  Formal_Typ := Root_Type (Formal_Typ);
               end if;

               --  From concurrent type to corresponding record

               if To_Corresponding then
                  if Is_Concurrent_Type (Formal_Typ)
                    and then Present (Corresponding_Record_Type (Formal_Typ))
                    and then
                      Present (Interfaces
                                 (Corresponding_Record_Type (Formal_Typ)))
                  then
                     Set_Etype (Formal,
                       Corresponding_Record_Type (Formal_Typ));
                  end if;

               --  From corresponding record to concurrent type

               else
                  if Is_Concurrent_Record_Type (Formal_Typ)
                    and then Present (Interfaces (Formal_Typ))
                  then
                     Set_Etype (Formal,
                       Corresponding_Concurrent_Type (Formal_Typ));
                  end if;
               end if;

               Next_Formal (Formal);
            end loop;
         end Replace_Types;

      --  Start of processing for Disambiguate_Spec

      begin
         --  Try to retrieve the specification of the body as is. All error
         --  messages are suppressed because the body may not have a spec in
         --  its current state.

         Spec_N := Find_Corresponding_Spec (N, False);

         --  It is possible that this is the body of a primitive declared
         --  between a private and a full view of a concurrent type. The
         --  controlling parameter of the spec carries the concurrent type,
         --  not the corresponding record type as transformed by Analyze_
         --  Subprogram_Specification. In such cases, we undo the change
         --  made by the analysis of the specification and try to find the
         --  spec again.

         --  Note that wrappers already have their corresponding specs and
         --  bodies set during their creation, so if the candidate spec is
         --  a wrapper, then we definitely need to swap all types to their
         --  original concurrent status.

         if No (Spec_N)
           or else Is_Primitive_Wrapper (Spec_N)
         then
            --  Restore all references of corresponding record types to the
            --  original concurrent types.

            Replace_Types (To_Corresponding => False);
            Priv_Spec := Find_Corresponding_Spec (N, False);

            --  The current body truly belongs to a primitive declared between
            --  a private and a full view. We leave the modified body as is,
            --  and return the true spec.

            if Present (Priv_Spec)
              and then Is_Private_Primitive (Priv_Spec)
            then
               return Priv_Spec;
            end if;

            --  In case that this is some sort of error, restore the original
            --  state of the body.

            Replace_Types (To_Corresponding => True);
         end if;

         return Spec_N;
      end Disambiguate_Spec;

      ----------------------------
      -- Exchange_Limited_Views --
      ----------------------------

      function Exchange_Limited_Views (Subp_Id : Entity_Id) return Elist_Id is
         Result : Elist_Id := No_Elist;

         procedure Detect_And_Exchange (Id : Entity_Id);
         --  Determine whether Id's type denotes an incomplete type associated
         --  with a limited with clause and exchange the limited view with the
         --  non-limited one when available. Note that the non-limited view
         --  may exist because of a with_clause in another unit in the context,
         --  but cannot be used because the current view of the enclosing unit
         --  is still a limited view.

         -------------------------
         -- Detect_And_Exchange --
         -------------------------

         procedure Detect_And_Exchange (Id : Entity_Id) is
            Typ : constant Entity_Id := Etype (Id);
         begin
            if From_Limited_With (Typ)
              and then Has_Non_Limited_View (Typ)
              and then not From_Limited_With (Scope (Typ))
            then
               if No (Result) then
                  Result := New_Elmt_List;
               end if;

               Prepend_Elmt (Typ, Result);
               Prepend_Elmt (Id, Result);
               Set_Etype (Id, Non_Limited_View (Typ));
            end if;
         end Detect_And_Exchange;

         --  Local variables

         Formal : Entity_Id;

      --  Start of processing for Exchange_Limited_Views

      begin
         --  Do not process subprogram bodies as they already use the non-
         --  limited view of types.

         if Ekind (Subp_Id) not in E_Function | E_Procedure then
            return No_Elist;
         end if;

         --  Examine all formals and swap views when applicable

         Formal := First_Formal (Subp_Id);
         while Present (Formal) loop
            Detect_And_Exchange (Formal);

            Next_Formal (Formal);
         end loop;

         --  Process the return type of a function

         if Ekind (Subp_Id) = E_Function then
            Detect_And_Exchange (Subp_Id);
         end if;

         return Result;
      end Exchange_Limited_Views;

      ------------------------------------
      -- Generate_Minimum_Accessibility --
      ------------------------------------

      procedure Generate_Minimum_Accessibility
        (Extra_Access : Entity_Id;
         Related_Form : Entity_Id := Empty)
      is
         Loc      : constant Source_Ptr := Sloc (Body_Nod);
         Form     : Entity_Id;
         Obj_Node : Node_Id;
      begin
         --  When no related formal exists then we are dealing with an
         --  extra accessibility formal for a function result.

         if No (Related_Form) then
            Form := Extra_Access;
         else
            Form := Related_Form;
         end if;

         --  Create the minimum accessibility object

         Obj_Node :=
            Make_Object_Declaration (Loc,
             Defining_Identifier =>
               Make_Temporary
                 (Loc, 'A', Extra_Access),
             Object_Definition   => New_Occurrence_Of
                                      (Standard_Natural, Loc),
             Expression          =>
               Make_Attribute_Reference (Loc,
                 Prefix         => New_Occurrence_Of
                                     (Standard_Natural, Loc),
                 Attribute_Name => Name_Min,
                 Expressions    => New_List (
                   Make_Integer_Literal (Loc,
                     Scope_Depth (Body_Id)),
                   New_Occurrence_Of
                     (Extra_Access, Loc))));

         --  Add the new local object to the Minimum_Acc_Obj to
         --  be later prepended to the subprogram's list of
         --  declarations after we are sure all expansion is
         --  done.

         if Present (Minimum_Acc_Objs) then
            Prepend (Obj_Node, Minimum_Acc_Objs);
         else
            Minimum_Acc_Objs := New_List (Obj_Node);
         end if;

         --  Register the object and analyze it

         Set_Minimum_Accessibility
           (Form, Defining_Identifier (Obj_Node));

         Analyze (Obj_Node);
      end Generate_Minimum_Accessibility;

      -------------------------------------
      -- Is_Private_Concurrent_Primitive --
      -------------------------------------

      function Is_Private_Concurrent_Primitive
        (Subp_Id : Entity_Id) return Boolean
      is
         Formal_Typ : Entity_Id;

      begin
         if Present (First_Formal (Subp_Id)) then
            Formal_Typ := Etype (First_Formal (Subp_Id));

            if Is_Concurrent_Record_Type (Formal_Typ) then
               if Is_Class_Wide_Type (Formal_Typ) then
                  Formal_Typ := Root_Type (Formal_Typ);
               end if;

               Formal_Typ := Corresponding_Concurrent_Type (Formal_Typ);
            end if;

            --  The type of the first formal is a concurrent tagged type with
            --  a private view.

            return
              Is_Concurrent_Type (Formal_Typ)
                and then Is_Tagged_Type (Formal_Typ)
                and then Has_Private_Declaration (Formal_Typ);
         end if;

         return False;
      end Is_Private_Concurrent_Primitive;

      -------------------------
      -- Mask_Unfrozen_Types --
      -------------------------

      function Mask_Unfrozen_Types (Spec_Id : Entity_Id) return Elist_Id is
         Result : Elist_Id := No_Elist;

         function Mask_Type_Refs (Node : Node_Id) return Traverse_Result;
         --  Mask all types referenced in the subtree rooted at Node

         --------------------
         -- Mask_Type_Refs --
         --------------------

         function Mask_Type_Refs (Node : Node_Id) return Traverse_Result is
            procedure Mask_Type (Typ : Entity_Id);
            --  ??? what does this do?

            ---------------
            -- Mask_Type --
            ---------------

            procedure Mask_Type (Typ : Entity_Id) is
            begin
               --  Skip Itypes created by the preanalysis

               if Is_Itype (Typ)
                 and then Scope_Within_Or_Same (Scope (Typ), Spec_Id)
               then
                  return;
               end if;

               if not Is_Frozen (Typ) then
                  if Scope (Typ) /= Current_Scope then
                     Set_Is_Frozen (Typ);
                     Append_New_Elmt (Typ, Result);
                  else
                     Freeze_Before (N, Typ);
                  end if;
               end if;
            end Mask_Type;

         --  Start of processing for Mask_Type_Refs

         begin
            if Is_Entity_Name (Node) and then Present (Entity (Node)) then
               Mask_Type (Etype (Entity (Node)));

               if Ekind (Entity (Node)) in E_Component | E_Discriminant then
                  Mask_Type (Scope (Entity (Node)));
               end if;

            elsif Nkind (Node) in N_Aggregate | N_Null | N_Type_Conversion
              and then Present (Etype (Node))
            then
               Mask_Type (Etype (Node));
            end if;

            return OK;
         end Mask_Type_Refs;

         procedure Mask_References is new Traverse_Proc (Mask_Type_Refs);

         --  Local variables

         Return_Stmt : constant Node_Id :=
                         First (Statements (Handled_Statement_Sequence (N)));

      --  Start of processing for Mask_Unfrozen_Types

      begin
         pragma Assert (Nkind (Return_Stmt) = N_Simple_Return_Statement);

         Mask_References (Expression (Return_Stmt));

         return Result;
      end Mask_Unfrozen_Types;

      ------------------
      -- Move_Pragmas --
      ------------------

      procedure Move_Pragmas (From : Node_Id; To : Node_Id) is
         Decl       : Node_Id;
         Insert_Nod : Node_Id;
         Next_Decl  : Node_Id;

      begin
         pragma Assert (Nkind (From) = N_Subprogram_Body);

         --  The pragmas are moved in an order-preserving fashion

         Insert_Nod := To;

         --  Inspect the declarations of the subprogram body and relocate all
         --  candidate pragmas.

         Decl := First (Declarations (From));
         while Present (Decl) loop

            --  Preserve the following declaration for iteration purposes, due
            --  to possible relocation of a pragma.

            Next_Decl := Next (Decl);

            if Nkind (Decl) = N_Pragma then
               --  Copy pragma SPARK_Mode if present in the declarative list
               --  of subprogram body From and insert it after node To. This
               --  pragma should not be moved, as it applies to the body too.

               if Pragma_Name_Unmapped (Decl) = Name_SPARK_Mode then
                  Insert_After (Insert_Nod, New_Copy_Tree (Decl));

               --  Move relevant pragmas to the spec

               elsif Pragma_Name_Unmapped (Decl) in Name_Depends
                                                  | Name_Ghost
                                                  | Name_Global
                                                  | Name_Pre
                                                  | Name_Precondition
                                                  | Name_Post
                                                  | Name_Refined_Depends
                                                  | Name_Refined_Global
                                                  | Name_Refined_Post
                                                  | Name_Inline
                                                  | Name_Pure_Function
                                                  | Name_Volatile_Function
               then
                  Remove (Decl);
                  Insert_After (Insert_Nod, Decl);
                  Insert_Nod := Decl;
               end if;

            --  Skip internally generated code

            elsif not Comes_From_Source (Decl) then
               null;

            --  No candidate pragmas are available for relocation

            else
               exit;
            end if;

            Decl := Next_Decl;
         end loop;
      end Move_Pragmas;

      ---------------------------
      -- Restore_Limited_Views --
      ---------------------------

      procedure Restore_Limited_Views (Restore_List : Elist_Id) is
         Elmt : Elmt_Id := First_Elmt (Restore_List);
         Id   : Entity_Id;

      begin
         while Present (Elmt) loop
            Id := Node (Elmt);
            Next_Elmt (Elmt);
            Set_Etype (Id, Node (Elmt));
            Next_Elmt (Elmt);
         end loop;
      end Restore_Limited_Views;

      ----------------------------
      -- Set_Trivial_Subprogram --
      ----------------------------

      procedure Set_Trivial_Subprogram (N : Node_Id) is
         Nxt : constant Node_Id := Next (N);

      begin
         Set_Is_Trivial_Subprogram (Body_Id);

         if Present (Spec_Id) then
            Set_Is_Trivial_Subprogram (Spec_Id);
         end if;

         if Present (Nxt)
           and then Nkind (Nxt) = N_Simple_Return_Statement
           and then No (Next (Nxt))
           and then Present (Expression (Nxt))
           and then Is_Entity_Name (Expression (Nxt))
         then
            Set_Never_Set_In_Source (Entity (Expression (Nxt)), False);
         end if;
      end Set_Trivial_Subprogram;

      ---------------------------
      -- Unmask_Unfrozen_Types --
      ---------------------------

      procedure Unmask_Unfrozen_Types (Unmask_List : Elist_Id) is
         Elmt : Elmt_Id := First_Elmt (Unmask_List);

      begin
         while Present (Elmt) loop
            Set_Is_Frozen (Node (Elmt), False);
            Next_Elmt (Elmt);
         end loop;
      end Unmask_Unfrozen_Types;

      ---------------------------------
      -- Verify_Overriding_Indicator --
      ---------------------------------

      procedure Verify_Overriding_Indicator is
      begin
         if Must_Override (Body_Spec) then
            if Nkind (Spec_Id) = N_Defining_Operator_Symbol
              and then Operator_Matches_Spec (Spec_Id, Spec_Id)
            then
               null;

            --  Overridden controlled primitives may have had their
            --  Overridden_Operation field cleared according to the setting of
            --  the Is_Hidden flag. An issue arises, however, when analyzing
            --  an instance that may have manipulated the flag during
            --  expansion. As a result, we add an exception for this case.

            elsif not Present (Overridden_Operation (Spec_Id))
              and then not (Chars (Spec_Id) in Name_Adjust
                                             | Name_Finalize
                                             | Name_Initialize
                             and then In_Instance)
            then
               Error_Msg_NE
                 ("subprogram& is not overriding", Body_Spec, Spec_Id);

            --  Overriding indicators aren't allowed for protected subprogram
            --  bodies (see the Confirmation in Ada Comment AC95-00213). Change
            --  this to a warning if -gnatd.E is enabled.

            elsif Ekind (Scope (Spec_Id)) = E_Protected_Type then
               Error_Msg_Warn := Error_To_Warning;
               Error_Msg_N
                 ("<<overriding indicator not allowed for protected "
                  & "subprogram body", Body_Spec);
            end if;

         elsif Must_Not_Override (Body_Spec) then
            if Present (Overridden_Operation (Spec_Id)) then
               Error_Msg_NE
                 ("subprogram& overrides inherited operation",
                  Body_Spec, Spec_Id);

            elsif Nkind (Spec_Id) = N_Defining_Operator_Symbol
              and then Operator_Matches_Spec (Spec_Id, Spec_Id)
            then
               Error_Msg_NE
                 ("subprogram& overrides predefined operator",
                    Body_Spec, Spec_Id);

            --  Overriding indicators aren't allowed for protected subprogram
            --  bodies (see the Confirmation in Ada Comment AC95-00213). Change
            --  this to a warning if -gnatd.E is enabled.

            elsif Ekind (Scope (Spec_Id)) = E_Protected_Type then
               Error_Msg_Warn := Error_To_Warning;

               Error_Msg_N
                 ("<<overriding indicator not allowed "
                  & "for protected subprogram body", Body_Spec);

            --  If this is not a primitive operation, then the overriding
            --  indicator is altogether illegal.

            elsif not Is_Primitive (Spec_Id) then
               Error_Msg_N
                 ("overriding indicator only allowed "
                  & "if subprogram is primitive", Body_Spec);
            end if;

         --  If checking the style rule and the operation overrides, then
         --  issue a warning about a missing overriding_indicator. Protected
         --  subprogram bodies are excluded from this style checking, since
         --  they aren't primitives (even though their declarations can
         --  override) and aren't allowed to have an overriding_indicator.

         elsif Style_Check
           and then Present (Overridden_Operation (Spec_Id))
           and then Ekind (Scope (Spec_Id)) /= E_Protected_Type
         then
            pragma Assert (Unit_Declaration_Node (Body_Id) = N);
            Style.Missing_Overriding (N, Body_Id);

         elsif Style_Check
           and then Can_Override_Operator (Spec_Id)
           and then not In_Predefined_Unit (Spec_Id)
         then
            pragma Assert (Unit_Declaration_Node (Body_Id) = N);
            Style.Missing_Overriding (N, Body_Id);
         end if;
      end Verify_Overriding_Indicator;

      --  Local variables

      Saved_GM   : constant Ghost_Mode_Type := Ghost_Mode;
      Saved_IGR  : constant Node_Id         := Ignored_Ghost_Region;
      Saved_EA   : constant Boolean         := Expander_Active;
      Saved_ISMP : constant Boolean         :=
                     Ignore_SPARK_Mode_Pragmas_In_Instance;
      --  Save the Ghost and SPARK mode-related data to restore on exit

   --  Start of processing for Analyze_Subprogram_Body_Helper

   begin
      --  A [generic] subprogram body freezes the contract of the nearest
      --  enclosing package body and all other contracts encountered in the
      --  same declarative part up to and excluding the subprogram body:

      --    package body Nearest_Enclosing_Package
      --      with Refined_State => (State => Constit)
      --    is
      --       Constit : ...;

      --       procedure Freezes_Enclosing_Package_Body
      --         with Refined_Depends => (Input => Constit) ...

      --  This ensures that any annotations referenced by the contract of the
      --  [generic] subprogram body are available. This form of freezing is
      --  decoupled from the usual Freeze_xxx mechanism because it must also
      --  work in the context of generics where normal freezing is disabled.

      --  Only bodies coming from source should cause this type of freezing.
      --  Expression functions that act as bodies and complete an initial
      --  declaration must be included in this category, hence the use of
      --  Original_Node.

      if Comes_From_Source (Original_Node (N)) then
         Freeze_Previous_Contracts (N);
      end if;

      --  Generic subprograms are handled separately. They always have a
      --  generic specification. Determine whether current scope has a
      --  previous declaration.

      --  If the subprogram body is defined within an instance of the same
      --  name, the instance appears as a package renaming, and will be hidden
      --  within the subprogram.

      if Present (Prev_Id)
        and then not Is_Overloadable (Prev_Id)
        and then (Nkind (Parent (Prev_Id)) /= N_Package_Renaming_Declaration
                   or else Comes_From_Source (Prev_Id))
      then
         if Is_Generic_Subprogram (Prev_Id) then
            Spec_Id := Prev_Id;

            --  A subprogram body is Ghost when it is stand-alone and subject
            --  to pragma Ghost or when the corresponding spec is Ghost. Set
            --  the mode now to ensure that any nodes generated during analysis
            --  and expansion are properly marked as Ghost.

            Mark_And_Set_Ghost_Body (N, Spec_Id);

            --  If the body completes the initial declaration of a compilation
            --  unit which is subject to pragma Elaboration_Checks, set the
            --  model specified by the pragma because it applies to all parts
            --  of the unit.

            Install_Elaboration_Model (Spec_Id);

            Set_Is_Compilation_Unit (Body_Id, Is_Compilation_Unit (Spec_Id));
            Set_Is_Child_Unit       (Body_Id, Is_Child_Unit       (Spec_Id));

            Analyze_Generic_Subprogram_Body (N, Spec_Id);

            if Nkind (N) = N_Subprogram_Body then
               HSS := Handled_Statement_Sequence (N);
               Check_Missing_Return;
            end if;

            goto Leave;

         --  Otherwise a previous entity conflicts with the subprogram name.
         --  Attempting to enter name will post error.

         else
            Enter_Name (Body_Id);
            goto Leave;
         end if;

      --  Non-generic case, find the subprogram declaration, if one was seen,
      --  or enter new overloaded entity in the current scope. If the
      --  Current_Entity is the Body_Id itself, the unit is being analyzed as
      --  part of the context of one of its subunits. No need to redo the
      --  analysis.

      elsif Prev_Id = Body_Id and then Has_Completion (Body_Id) then
         goto Leave;

      else
         Body_Id := Analyze_Subprogram_Specification (Body_Spec);

         if Nkind (N) = N_Subprogram_Body_Stub
           or else No (Corresponding_Spec (N))
         then
            if Is_Private_Concurrent_Primitive (Body_Id) then
               Spec_Id := Disambiguate_Spec;

               --  A subprogram body is Ghost when it is stand-alone and
               --  subject to pragma Ghost or when the corresponding spec is
               --  Ghost. Set the mode now to ensure that any nodes generated
               --  during analysis and expansion are properly marked as Ghost.

               Mark_And_Set_Ghost_Body (N, Spec_Id);

               --  If the body completes a compilation unit which is subject
               --  to pragma Elaboration_Checks, set the model specified by
               --  the pragma because it applies to all parts of the unit.

               Install_Elaboration_Model (Spec_Id);

            else
               Spec_Id := Find_Corresponding_Spec (N);

               --  A subprogram body is Ghost when it is stand-alone and
               --  subject to pragma Ghost or when the corresponding spec is
               --  Ghost. Set the mode now to ensure that any nodes generated
               --  during analysis and expansion are properly marked as Ghost.

               Mark_And_Set_Ghost_Body (N, Spec_Id);

               --  If the body completes a compilation unit which is subject
               --  to pragma Elaboration_Checks, set the model specified by
               --  the pragma because it applies to all parts of the unit.

               Install_Elaboration_Model (Spec_Id);

               --  In GNATprove mode, if the body has no previous spec, create
               --  one so that the inlining machinery can operate properly.
               --  Transfer aspects, if any, to the new spec, so that they
               --  are legal and can be processed ahead of the body.
               --  We make two copies of the given spec, one for the new
               --  declaration, and one for the body.
               --  ??? This should be conditioned on front-end inlining rather
               --  than GNATprove_Mode.

               if No (Spec_Id) and then GNATprove_Mode

                 --  Inlining does not apply during preanalysis of code

                 and then Full_Analysis

                 --  Inlining only applies to full bodies, not stubs

                 and then Nkind (N) /= N_Subprogram_Body_Stub

                 --  Inlining only applies to bodies in the source code, not to
                 --  those generated by the compiler. In particular, expression
                 --  functions, whose body is generated by the compiler, are
                 --  treated specially by GNATprove.

                 and then Comes_From_Source (Body_Id)

                 --  This cannot be done for a compilation unit, which is not
                 --  in a context where we can insert a new spec.

                 and then Is_List_Member (N)

                 --  Inlining only applies to subprograms without contracts,
                 --  as a contract is a sign that GNATprove should perform a
                 --  modular analysis of the subprogram instead of a contextual
                 --  analysis at each call site. The same test is performed in
                 --  Inline.Can_Be_Inlined_In_GNATprove_Mode. It is repeated
                 --  here in another form (because the contract has not been
                 --  attached to the body) to avoid front-end errors in case
                 --  pragmas are used instead of aspects, because the
                 --  corresponding pragmas in the body would not be transferred
                 --  to the spec, leading to legality errors.

                 and then not Body_Has_Contract
                 and then not Inside_A_Generic
               then
                  Build_Subprogram_Declaration;

               --  If this is a function that returns a constrained array, and
               --  Transform_Function_Array is set, create subprogram
               --  declaration to simplify e.g. subsequent C generation.

               elsif No (Spec_Id)
                 and then Transform_Function_Array
                 and then Nkind (Body_Spec) = N_Function_Specification
                 and then Is_Array_Type (Etype (Body_Id))
                 and then Is_Constrained (Etype (Body_Id))
               then
                  Build_Subprogram_Declaration;
               end if;
            end if;

            --  If this is a duplicate body, no point in analyzing it

            if Error_Posted (N) then
               goto Leave;
            end if;

            --  A subprogram body should cause freezing of its own declaration,
            --  but if there was no previous explicit declaration, then the
            --  subprogram will get frozen too late (there may be code within
            --  the body that depends on the subprogram having been frozen,
            --  such as uses of extra formals), so we force it to be frozen
            --  here. Same holds if the body and spec are compilation units.
            --  Finally, if the return type is an anonymous access to protected
            --  subprogram, it must be frozen before the body because its
            --  expansion has generated an equivalent type that is used when
            --  elaborating the body.

            --  An exception in the case of Ada 2012, AI05-177: The bodies
            --  created for expression functions do not freeze.

            if No (Spec_Id)
              and then Nkind (Original_Node (N)) /= N_Expression_Function
            then
               Freeze_Before (N, Body_Id);

            elsif Nkind (Parent (N)) = N_Compilation_Unit then
               Freeze_Before (N, Spec_Id);

            elsif Is_Access_Subprogram_Type (Etype (Body_Id)) then
               Freeze_Before (N, Etype (Body_Id));
            end if;

         else
            Spec_Id := Corresponding_Spec (N);

            --  A subprogram body is Ghost when it is stand-alone and subject
            --  to pragma Ghost or when the corresponding spec is Ghost. Set
            --  the mode now to ensure that any nodes generated during analysis
            --  and expansion are properly marked as Ghost.

            Mark_And_Set_Ghost_Body (N, Spec_Id);

            --  If the body completes the initial declaration of a compilation
            --  unit which is subject to pragma Elaboration_Checks, set the
            --  model specified by the pragma because it applies to all parts
            --  of the unit.

            Install_Elaboration_Model (Spec_Id);
         end if;
      end if;

      --  Deactivate expansion inside the body of ignored Ghost entities,
      --  as this code will ultimately be ignored. This avoids requiring the
      --  presence of run-time units which are not needed. Only do this for
      --  user entities, as internally generated entitities might still need
      --  to be expanded (e.g. those generated for types).

      if Present (Ignored_Ghost_Region)
        and then Comes_From_Source (Body_Id)
      then
         Expander_Active := False;
      end if;

      --  Previously we scanned the body to look for nested subprograms, and
      --  rejected an inline directive if nested subprograms were present,
      --  because the back-end would generate conflicting symbols for the
      --  nested bodies. This is now unnecessary.

      --  Look ahead to recognize a pragma Inline that appears after the body

      Check_Inline_Pragma (Spec_Id);

      --  Deal with special case of a fully private operation in the body of
      --  the protected type. We must create a declaration for the subprogram,
      --  in order to attach the subprogram that will be used in internal
      --  calls. We exclude compiler generated bodies from the expander since
      --  the issue does not arise for those cases.

      if No (Spec_Id)
        and then Comes_From_Source (N)
        and then Is_Protected_Type (Current_Scope)
      then
         Spec_Id := Build_Internal_Protected_Declaration (N);
      end if;

      --  If Transform_Function_Array is set and this is a function returning a
      --  constrained array type for which we must create a procedure with an
      --  extra out parameter, build and analyze the body now. The procedure
      --  declaration has already been created. We reuse the source body of the
      --  function, because in an instance it may contain global references
      --  that cannot be reanalyzed. The source function itself is not used any
      --  further, so we mark it as having a completion. If the subprogram is a
      --  stub the transformation is done later, when the proper body is
      --  analyzed.

      if Expander_Active
        and then Transform_Function_Array
        and then Nkind (N) /= N_Subprogram_Body_Stub
      then
         declare
            S         : constant Entity_Id :=
                          (if Present (Spec_Id)
                           then Spec_Id
                           else Defining_Unit_Name (Specification (N)));
            Proc_Body : Node_Id;

         begin
            if Ekind (S) = E_Function and then Rewritten_For_C (S) then
               Set_Has_Completion (S);
               Proc_Body := Build_Procedure_Body_Form (S, N);

               if Present (Spec_Id) then
                  Rewrite (N, Proc_Body);
                  Analyze (N);

                  --  The entity for the created procedure must remain
                  --  invisible, so it does not participate in resolution of
                  --  subsequent references to the function.

                  Set_Is_Immediately_Visible (Corresponding_Spec (N), False);

               --  If we do not have a separate spec for N, build one and
               --  insert the new body right after.

               else
                  Rewrite (N,
                    Make_Subprogram_Declaration (Loc,
                      Specification => Relocate_Node (Specification (N))));
                  Analyze (N);
                  Insert_After_And_Analyze (N, Proc_Body);
                  Set_Is_Immediately_Visible
                    (Corresponding_Spec (Proc_Body), False);
               end if;

               goto Leave;
            end if;
         end;
      end if;

      --  If a separate spec is present, then deal with freezing issues

      if Present (Spec_Id) then
         Spec_Decl := Unit_Declaration_Node (Spec_Id);
         Verify_Overriding_Indicator;

         --  In general, the spec will be frozen when we start analyzing the
         --  body. However, for internally generated operations, such as
         --  wrapper functions for inherited operations with controlling
         --  results, the spec may not have been frozen by the time we expand
         --  the freeze actions that include the bodies. In particular, extra
         --  formals for accessibility or for return-in-place may need to be
         --  generated. Freeze nodes, if any, are inserted before the current
         --  body. These freeze actions are also needed in Compile_Only mode to
         --  enable the proper back-end type annotations.
         --  They are necessary in any case to ensure proper elaboration order
         --  in gigi.

         if Nkind (N) = N_Subprogram_Body
           and then Was_Expression_Function (N)
           and then not Has_Completion (Spec_Id)
           and then Serious_Errors_Detected = 0
           and then (Expander_Active
                      or else Operating_Mode = Check_Semantics
                      or else Is_Ignored_Ghost_Entity (Spec_Id))
         then
            --  The body generated for an expression function that is not a
            --  completion is a freeze point neither for the profile nor for
            --  anything else. That's why, in order to prevent any freezing
            --  during analysis, we need to mask types declared outside the
            --  expression (and in an outer scope) that are not yet frozen.
            --  This also needs to be done in the case of an ignored Ghost
            --  expression function, where the expander isn't active.

            Set_Is_Frozen (Spec_Id);
            Mask_Types := Mask_Unfrozen_Types (Spec_Id);

         elsif not Is_Frozen (Spec_Id)
           and then Serious_Errors_Detected = 0
         then
            Set_Has_Delayed_Freeze (Spec_Id);
            Freeze_Before (N, Spec_Id);
         end if;
      end if;

      --  If the subprogram has a class-wide clone, build its body as a copy
      --  of the original body, and rewrite body of original subprogram as a
      --  wrapper that calls the clone. If N is a stub, this construction will
      --  take place when the proper body is analyzed. No action needed if this
      --  subprogram has been eliminated.

      if Present (Spec_Id)
        and then Present (Class_Wide_Clone (Spec_Id))
        and then (Comes_From_Source (N) or else Was_Expression_Function (N))
        and then Nkind (N) /= N_Subprogram_Body_Stub
        and then not (Expander_Active and then Is_Eliminated (Spec_Id))
      then
         Build_Class_Wide_Clone_Body (Spec_Id, N);

         --  This is the new body for the existing primitive operation

         Rewrite (N, Build_Class_Wide_Clone_Call
           (Sloc (N), New_List, Spec_Id, Parent (Spec_Id)));
         Set_Has_Completion (Spec_Id, False);
         Analyze (N);
         return;
      end if;

      --  Place subprogram on scope stack, and make formals visible. If there
      --  is a spec, the visible entity remains that of the spec.

      if Present (Spec_Id) then
         Generate_Reference (Spec_Id, Body_Id, 'b', Set_Ref => False);

         if Is_Child_Unit (Spec_Id) then
            Generate_Reference (Spec_Id, Scope (Spec_Id), 'k', False);
         end if;

         if Style_Check then
            Style.Check_Identifier (Body_Id, Spec_Id);
         end if;

         Set_Is_Compilation_Unit (Body_Id, Is_Compilation_Unit (Spec_Id));
         Set_Is_Child_Unit       (Body_Id, Is_Child_Unit       (Spec_Id));

         if Is_Abstract_Subprogram (Spec_Id) then
            Error_Msg_N ("an abstract subprogram cannot have a body", N);
            goto Leave;

         else
            Set_Convention (Body_Id, Convention (Spec_Id));
            Set_Has_Completion (Spec_Id);

            if Is_Protected_Type (Scope (Spec_Id)) then
               Prot_Typ := Scope (Spec_Id);
            end if;

            --  If this is a body generated for a renaming, do not check for
            --  full conformance. The check is redundant, because the spec of
            --  the body is a copy of the spec in the renaming declaration,
            --  and the test can lead to spurious errors on nested defaults.

            if Present (Spec_Decl)
              and then not Comes_From_Source (N)
              and then
                (Nkind (Original_Node (Spec_Decl)) =
                                          N_Subprogram_Renaming_Declaration
                  or else (Present (Corresponding_Body (Spec_Decl))
                            and then
                              Nkind (Unit_Declaration_Node
                                       (Corresponding_Body (Spec_Decl))) =
                                          N_Subprogram_Renaming_Declaration))
            then
               Conformant := True;

            --  Conversely, the spec may have been generated for specless body
            --  with an inline pragma. The entity comes from source, which is
            --  both semantically correct and necessary for proper inlining.
            --  The subprogram declaration itself is not in the source.

            elsif Comes_From_Source (N)
              and then Present (Spec_Decl)
              and then not Comes_From_Source (Spec_Decl)
              and then Has_Pragma_Inline (Spec_Id)
            then
               Conformant := True;

            else
               Check_Conformance
                 (Body_Id, Spec_Id,
                  Fully_Conformant, True, Conformant, Body_Id);
            end if;

            --  If the body is not fully conformant, we have to decide if we
            --  should analyze it or not. If it has a really messed up profile
            --  then we probably should not analyze it, since we will get too
            --  many bogus messages.

            --  Our decision is to go ahead in the non-fully conformant case
            --  only if it is at least mode conformant with the spec. Note
            --  that the call to Check_Fully_Conformant has issued the proper
            --  error messages to complain about the lack of conformance.

            if not Conformant
              and then not Mode_Conformant (Body_Id, Spec_Id)
            then
               goto Leave;
            end if;
         end if;

         --  In the case we are dealing with an expression function we check
         --  the formals attached to the spec instead of the body - so we don't
         --  reference body formals.

         if Spec_Id /= Body_Id
           and then not Is_Expression_Function (Spec_Id)
         then
            Reference_Body_Formals (Spec_Id, Body_Id);
         end if;

         Reinit_Field_To_Zero (Body_Id, Has_Out_Or_In_Out_Parameter);
         Reinit_Field_To_Zero (Body_Id, Needs_No_Actuals,
           Old_Ekind => (E_Function | E_Procedure => True, others => False));
         Reinit_Field_To_Zero (Body_Id, Is_Predicate_Function,
           Old_Ekind => (E_Function | E_Procedure => True, others => False));
         Reinit_Field_To_Zero (Body_Id, Protected_Subprogram,
           Old_Ekind => (E_Function | E_Procedure => True, others => False));

         if Ekind (Body_Id) = E_Procedure then
            Reinit_Field_To_Zero (Body_Id, Receiving_Entry);
         end if;

         Mutate_Ekind (Body_Id, E_Subprogram_Body);

         if Nkind (N) = N_Subprogram_Body_Stub then
            Set_Corresponding_Spec_Of_Stub (N, Spec_Id);

         --  Regular body

         else
            Set_Corresponding_Spec (N, Spec_Id);

            --  Ada 2005 (AI-345): If the operation is a primitive operation
            --  of a concurrent type, the type of the first parameter has been
            --  replaced with the corresponding record, which is the proper
            --  run-time structure to use. However, within the body there may
            --  be uses of the formals that depend on primitive operations
            --  of the type (in particular calls in prefixed form) for which
            --  we need the original concurrent type. The operation may have
            --  several controlling formals, so the replacement must be done
            --  for all of them.

            if Comes_From_Source (Spec_Id)
              and then Present (First_Entity (Spec_Id))
              and then Ekind (Etype (First_Entity (Spec_Id))) = E_Record_Type
              and then Is_Tagged_Type (Etype (First_Entity (Spec_Id)))
              and then Present (Interfaces (Etype (First_Entity (Spec_Id))))
              and then Present (Corresponding_Concurrent_Type
                                  (Etype (First_Entity (Spec_Id))))
            then
               declare
                  Typ  : constant Entity_Id := Etype (First_Entity (Spec_Id));
                  Form : Entity_Id;

               begin
                  Form := First_Formal (Spec_Id);
                  while Present (Form) loop
                     if Etype (Form) = Typ then
                        Set_Etype (Form, Corresponding_Concurrent_Type (Typ));
                     end if;

                     Next_Formal (Form);
                  end loop;
               end;
            end if;

            --  Make the formals visible, and place subprogram on scope stack.
            --  This is also the point at which we set Last_Real_Spec_Entity
            --  to mark the entities which will not be moved to the body.

            Install_Formals (Spec_Id);
            Last_Real_Spec_Entity := Last_Entity (Spec_Id);

            --  Within an instance, add local renaming declarations so that
            --  gdb can retrieve the values of actuals more easily. This is
            --  only relevant if generating code.

            if Is_Generic_Instance (Spec_Id)
              and then Is_Wrapper_Package (Current_Scope)
              and then Expander_Active
            then
               Build_Subprogram_Instance_Renamings (N, Current_Scope);
            end if;

            Push_Scope (Spec_Id);

            --  Make sure that the subprogram is immediately visible. For
            --  child units that have no separate spec this is indispensable.
            --  Otherwise it is safe albeit redundant.

            Set_Is_Immediately_Visible (Spec_Id);
         end if;

         Set_Corresponding_Body (Unit_Declaration_Node (Spec_Id), Body_Id);
         Set_Is_Obsolescent (Body_Id, Is_Obsolescent (Spec_Id));
         Set_Scope          (Body_Id, Scope (Spec_Id));

      --  Case of subprogram body with no previous spec

      else
         --  Check for style warning required

         if Style_Check

           --  Only apply check for source level subprograms for which checks
           --  have not been suppressed.

           and then Comes_From_Source (Body_Id)
           and then not Suppress_Style_Checks (Body_Id)

           --  No warnings within an instance

           and then not In_Instance

           --  No warnings for expression functions

           and then Nkind (Original_Node (N)) /= N_Expression_Function
         then
            Style.Body_With_No_Spec (N);
         end if;

         New_Overloaded_Entity (Body_Id);

         if Nkind (N) /= N_Subprogram_Body_Stub then
            Set_Acts_As_Spec (N);
            Generate_Definition (Body_Id);
            Generate_Reference
              (Body_Id, Body_Id, 'b', Set_Ref => False, Force => True);

            --  If the body is an entry wrapper created for an entry with
            --  preconditions, it must be compiled in the context of the
            --  enclosing synchronized object, because it may mention other
            --  operations of the type.

            if Is_Entry_Wrapper (Body_Id) then
               declare
                  Prot : constant Entity_Id := Etype (First_Entity (Body_Id));
               begin
                  Push_Scope (Prot);
                  Install_Declarations (Prot);
               end;
            end if;

            Install_Formals (Body_Id);

            Push_Scope (Body_Id);
         end if;

         --  For stubs and bodies with no previous spec, generate references to
         --  formals.

         Generate_Reference_To_Formals (Body_Id);
      end if;

      --  Entry barrier functions are generated outside the protected type and
      --  should not carry the SPARK_Mode of the enclosing context.

      if Nkind (N) = N_Subprogram_Body
        and then Is_Entry_Barrier_Function (N)
      then
         null;

      --  The body is generated as part of expression function expansion. When
      --  the expression function appears in the visible declarations of a
      --  package, the body is added to the private declarations. Since both
      --  declarative lists may be subject to a different SPARK_Mode, inherit
      --  the mode of the spec.

      --    package P with SPARK_Mode is
      --       function Expr_Func ... is (...);         --  original
      --       [function Expr_Func ...;]                --  generated spec
      --                                                --    mode is ON
      --    private
      --       pragma SPARK_Mode (Off);
      --       [function Expr_Func ... is return ...;]  --  generated body
      --    end P;                                      --    mode is ON

      elsif not Comes_From_Source (N)
        and then Present (Spec_Id)
        and then Is_Expression_Function (Spec_Id)
      then
         Set_SPARK_Pragma (Body_Id, SPARK_Pragma (Spec_Id));
         Set_SPARK_Pragma_Inherited
           (Body_Id, SPARK_Pragma_Inherited (Spec_Id));

      --  Set the SPARK_Mode from the current context (may be overwritten later
      --  with explicit pragma). Exclude the case where the SPARK_Mode appears
      --  initially on a stand-alone subprogram body, but is then relocated to
      --  a generated corresponding spec. In this scenario the mode is shared
      --  between the spec and body.

      elsif No (SPARK_Pragma (Body_Id)) then
         Set_SPARK_Pragma           (Body_Id, SPARK_Mode_Pragma);
         Set_SPARK_Pragma_Inherited (Body_Id);
      end if;

      --  A subprogram body may be instantiated or inlined at a later pass.
      --  Restore the state of Ignore_SPARK_Mode_Pragmas_In_Instance when it
      --  applied to the initial declaration of the body.

      if Present (Spec_Id) then
         if Ignore_SPARK_Mode_Pragmas (Spec_Id) then
            Ignore_SPARK_Mode_Pragmas_In_Instance := True;
         end if;

      else
         --  Save the state of flag Ignore_SPARK_Mode_Pragmas_In_Instance in
         --  case the body is instantiated or inlined later and out of context.
         --  The body uses this attribute to restore the value of the global
         --  flag.

         if Ignore_SPARK_Mode_Pragmas_In_Instance then
            Set_Ignore_SPARK_Mode_Pragmas (Body_Id);

         elsif Ignore_SPARK_Mode_Pragmas (Body_Id) then
            Ignore_SPARK_Mode_Pragmas_In_Instance := True;
         end if;
      end if;

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

      if No (Spec_Id) then
         Mark_Elaboration_Attributes
           (N_Id     => Body_Id,
            Checks   => True,
            Warnings => True);
      end if;

      --  If this is the proper body of a stub, we must verify that the stub
      --  conforms to the body, and to the previous spec if one was present.
      --  We know already that the body conforms to that spec. This test is
      --  only required for subprograms that come from source.

      if Nkind (Parent (N)) = N_Subunit
        and then Comes_From_Source (N)
        and then not Error_Posted (Body_Id)
        and then Nkind (Corresponding_Stub (Parent (N))) =
                                                N_Subprogram_Body_Stub
      then
         declare
            Old_Id : constant Entity_Id :=
                       Defining_Entity
                         (Specification (Corresponding_Stub (Parent (N))));

            Conformant : Boolean := False;

         begin
            if No (Spec_Id) then
               Check_Fully_Conformant (Body_Id, Old_Id);

            else
               Check_Conformance
                 (Body_Id, Old_Id, Fully_Conformant, False, Conformant);

               if not Conformant then

                  --  The stub was taken to be a new declaration. Indicate that
                  --  it lacks a body.

                  Set_Has_Completion (Old_Id, False);
               end if;
            end if;
         end;
      end if;

      Set_Has_Completion (Body_Id);
      Check_Eliminated (Body_Id);

      --  Analyze any aspect specifications that appear on the subprogram body
      --  stub. Stop the analysis now as the stub does not have a declarative
      --  or a statement part, and it cannot be inlined.

      if Nkind (N) = N_Subprogram_Body_Stub then
         if Has_Aspects (N) then
            Analyze_Aspects_On_Subprogram_Body_Or_Stub (N);
         end if;

         goto Leave;
      end if;

      --  Handle inlining

      if Expander_Active
        and then Serious_Errors_Detected = 0
        and then Present (Spec_Id)
        and then Has_Pragma_Inline (Spec_Id)
      then
         --  Legacy implementation (relying on front-end inlining)

         if not Back_End_Inlining then
            if Has_Pragma_Inline_Always (Spec_Id)
              or else (Front_End_Inlining
                        and then not Opt.Disable_FE_Inline)
            then
               Build_Body_To_Inline (N, Spec_Id);
            end if;

         --  New implementation (relying on back-end inlining)

         else
            if Has_Pragma_Inline_Always (Spec_Id)
              or else Optimization_Level > 0
            then
               --  Handle function returning an unconstrained type

               if Comes_From_Source (Body_Id)
                 and then Ekind (Spec_Id) = E_Function
                 and then Returns_Unconstrained_Type (Spec_Id)

                 --  If function builds in place, i.e. returns a limited type,
                 --  inlining cannot be done.

                 and then not Is_Limited_Type (Etype (Spec_Id))
               then
                  Check_And_Split_Unconstrained_Function (N, Spec_Id, Body_Id);

               else
                  declare
                     Subp_Body : constant Node_Id :=
                                   Unit_Declaration_Node (Body_Id);
                     Subp_Decl : constant List_Id := Declarations (Subp_Body);

                  begin
                     --  Do not pass inlining to the backend if the subprogram
                     --  has declarations or statements which cannot be inlined
                     --  by the backend. This check is done here to emit an
                     --  error instead of the generic warning message reported
                     --  by the GCC backend (ie. "function might not be
                     --  inlinable").

                     if Present (Subp_Decl)
                       and then Has_Excluded_Declaration (Spec_Id, Subp_Decl)
                     then
                        null;

                     elsif Has_Excluded_Statement
                             (Spec_Id,
                              Statements
                                (Handled_Statement_Sequence (Subp_Body)))
                     then
                        null;

                     --  If the backend inlining is available then at this
                     --  stage we only have to mark the subprogram as inlined.
                     --  The expander will take care of registering it in the
                     --  table of subprograms inlined by the backend a part of
                     --  processing calls to it (cf. Expand_Call)

                     else
                        Set_Is_Inlined (Spec_Id);
                     end if;
                  end;
               end if;
            end if;
         end if;

      --  In GNATprove mode, inline only when there is a separate subprogram
      --  declaration for now, as inlining of subprogram bodies acting as
      --  declarations, or subprogram stubs, are not supported by front-end
      --  inlining. This inlining should occur after analysis of the body, so
      --  that it is known whether the value of SPARK_Mode, which can be
      --  defined by a pragma inside the body, is applicable to the body.
      --  Inlining can be disabled with switch -gnatdm

      elsif GNATprove_Mode
        and then Full_Analysis
        and then not Inside_A_Generic
        and then Present (Spec_Id)
        and then
          Nkind (Unit_Declaration_Node (Spec_Id)) = N_Subprogram_Declaration
        and then Body_Has_SPARK_Mode_On
        and then Can_Be_Inlined_In_GNATprove_Mode (Spec_Id, Body_Id)
        and then not Body_Has_Contract
        and then not Debug_Flag_M
      then
         Build_Body_To_Inline (N, Spec_Id);
      end if;

      --  When generating code, inherited pre/postconditions are handled when
      --  expanding the corresponding contract.

      --  Ada 2005 (AI-262): In library subprogram bodies, after the analysis
      --  of the specification we have to install the private withed units.
      --  This holds for child units as well.

      if Is_Compilation_Unit (Body_Id)
        or else Nkind (Parent (N)) = N_Compilation_Unit
      then
         Install_Private_With_Clauses (Body_Id);
      end if;

      Check_Anonymous_Return;

      --  Set the Protected_Formal field of each extra formal of the protected
      --  subprogram to reference the corresponding extra formal of the
      --  subprogram that implements it. For regular formals this occurs when
      --  the protected subprogram's declaration is expanded, but the extra
      --  formals don't get created until the subprogram is frozen. We need to
      --  do this before analyzing the protected subprogram's body so that any
      --  references to the original subprogram's extra formals will be changed
      --  refer to the implementing subprogram's formals (see Expand_Formal).

      if Present (Spec_Id)
        and then Is_Protected_Type (Scope (Spec_Id))
        and then Present (Protected_Body_Subprogram (Spec_Id))
      then
         declare
            Impl_Subp       : constant Entity_Id :=
                                Protected_Body_Subprogram (Spec_Id);
            Prot_Ext_Formal : Entity_Id := Extra_Formals (Spec_Id);
            Impl_Ext_Formal : Entity_Id := Extra_Formals (Impl_Subp);

         begin
            while Present (Prot_Ext_Formal) loop
               pragma Assert (Present (Impl_Ext_Formal));
               Set_Protected_Formal (Prot_Ext_Formal, Impl_Ext_Formal);
               Next_Formal_With_Extras (Prot_Ext_Formal);
               Next_Formal_With_Extras (Impl_Ext_Formal);
            end loop;
         end;
      end if;

      --  Generate minimum accessibility local objects to correspond with
      --  any extra formal added for anonymous access types. This new local
      --  object can then be used instead of the formal in case it is used
      --  in an actual to a call to a nested subprogram.

      --  This method is used to supplement our "small integer model" for
      --  accessibility-check generation (for more information see
      --  Accessibility_Level).

      --  Because we allow accessibility values greater than our expected value
      --  passing along the same extra accessibility formal as an actual
      --  to a nested subprogram becomes a problem because high values mean
      --  different things to the callee even though they are the same to the
      --  caller. So, as described in the first section, we create a local
      --  object representing the minimum of the accessibility level value that
      --  is passed in and the accessibility level of the callee's parameter
      --  and locals and use it in the case of a call to a nested subprogram.
      --  This generated object is refered to as a "minimum accessiblity
      --  level."

      if Present (Spec_Id) or else Present (Body_Id) then
         Body_Nod := Unit_Declaration_Node (Body_Id);

         declare
            Form : Entity_Id;
         begin
            --  Grab the appropriate formal depending on whether there exists
            --  an actual spec for the subprogram or whether we are dealing
            --  with a protected subprogram.

            if Present (Spec_Id) then
               if Present (Protected_Body_Subprogram (Spec_Id)) then
                  Form := First_Formal (Protected_Body_Subprogram (Spec_Id));
               else
                  Form := First_Formal (Spec_Id);
               end if;
            else
               Form := First_Formal (Body_Id);
            end if;

            --  Loop through formals if the subprogram is capable of accepting
            --  a generated local object. If it is not then it is also not
            --  capable of having local subprograms meaning it would not need
            --  a minimum accessibility level object anyway.

            if Present (Body_Nod)
              and then Has_Declarations (Body_Nod)
              and then Nkind (Body_Nod) /= N_Package_Specification
            then
               while Present (Form) loop

                  if Present (Extra_Accessibility (Form))
                    and then No (Minimum_Accessibility (Form))
                  then
                     --  Generate the minimum accessibility level object

                     --    A60b : constant natural := natural'min(1, paramL);

                     Generate_Minimum_Accessibility
                       (Extra_Accessibility (Form), Form);
                  end if;

                  Next_Formal (Form);
               end loop;

               --  Generate the minimum accessibility level object for the
               --  function's Extra_Accessibility_Of_Result.

               --    A31b : constant natural := natural'min (2, funcL);

               if Ekind (Body_Id) = E_Function
                 and then Present (Extra_Accessibility_Of_Result (Body_Id))
               then
                  Generate_Minimum_Accessibility
                    (Extra_Accessibility_Of_Result (Body_Id));

                  --  Replace the Extra_Accessibility_Of_Result with the new
                  --  minimum accessibility object.

                  Set_Extra_Accessibility_Of_Result
                    (Body_Id, Minimum_Accessibility
                                (Extra_Accessibility_Of_Result (Body_Id)));
               end if;
            end if;
         end;
      end if;

      --  Now we can go on to analyze the body

      HSS := Handled_Statement_Sequence (N);
      Set_Actual_Subtypes (N, Current_Scope);

      --  Add a declaration for the Protection object, renaming declarations
      --  for discriminals and privals and finally a declaration for the entry
      --  family index (if applicable). This form of early expansion is done
      --  when the Expander is active because Install_Private_Data_Declarations
      --  references entities which were created during regular expansion. The
      --  subprogram entity must come from source, and not be an internally
      --  generated subprogram.

      if Expander_Active
        and then Present (Prot_Typ)
        and then Present (Spec_Id)
        and then Comes_From_Source (Spec_Id)
        and then not Is_Eliminated (Spec_Id)
      then
         Install_Private_Data_Declarations
           (Sloc (N), Spec_Id, Prot_Typ, N, Declarations (N));
      end if;

      --  Ada 2012 (AI05-0151): Incomplete types coming from a limited context
      --  may now appear in parameter and result profiles. Since the analysis
      --  of a subprogram body may use the parameter and result profile of the
      --  spec, swap any limited views with their non-limited counterpart.

      if Ada_Version >= Ada_2012 and then Present (Spec_Id) then
         Exch_Views := Exchange_Limited_Views (Spec_Id);
      end if;

      --  If the return type is an anonymous access type whose designated type
      --  is the limited view of a class-wide type and the non-limited view is
      --  available, update the return type accordingly.

      if Ada_Version >= Ada_2005 and then Present (Spec_Id) then
         declare
            Etyp : Entity_Id;
            Rtyp : Entity_Id;

         begin
            Rtyp := Etype (Spec_Id);

            if Ekind (Rtyp) = E_Anonymous_Access_Type then
               Etyp := Directly_Designated_Type (Rtyp);

               if Is_Class_Wide_Type (Etyp)
                 and then From_Limited_With (Etyp)
               then
                  Desig_View := Etyp;
                  Set_Directly_Designated_Type (Rtyp, Available_View (Etyp));
               end if;
            end if;
         end;
      end if;

      --  Analyze any aspect specifications that appear on the subprogram body

      if Has_Aspects (N) then
         Analyze_Aspects_On_Subprogram_Body_Or_Stub (N);
      end if;

      Analyze_Declarations (Declarations (N));

      --  Verify that the SPARK_Mode of the body agrees with that of its spec

      if Present (Spec_Id) and then Present (SPARK_Pragma (Body_Id)) then
         if Present (SPARK_Pragma (Spec_Id)) then
            if Get_SPARK_Mode_From_Annotation (SPARK_Pragma (Spec_Id)) = Off
                 and then
               Get_SPARK_Mode_From_Annotation (SPARK_Pragma (Body_Id)) = On
            then
               Error_Msg_Sloc := Sloc (SPARK_Pragma (Body_Id));
               Error_Msg_N ("incorrect application of SPARK_Mode#", N);
               Error_Msg_Sloc := Sloc (SPARK_Pragma (Spec_Id));
               Error_Msg_NE
                 ("\value Off was set for SPARK_Mode on & #", N, Spec_Id);
            end if;

         elsif Nkind (Parent (Parent (Spec_Id))) = N_Subprogram_Body_Stub then
            null;

         --  SPARK_Mode Off could complete no SPARK_Mode in a generic, either
         --  as specified in source code, or because SPARK_Mode On is ignored
         --  in an instance where the context is SPARK_Mode Off/Auto.

         elsif Get_SPARK_Mode_From_Annotation (SPARK_Pragma (Body_Id)) = Off
           and then (Is_Generic_Unit (Spec_Id) or else In_Instance)
         then
            null;

         else
            Error_Msg_Sloc := Sloc (SPARK_Pragma (Body_Id));
            Error_Msg_N ("incorrect application of SPARK_Mode #", N);
            Error_Msg_Sloc := Sloc (Spec_Id);
            Error_Msg_NE
              ("\no value was set for SPARK_Mode on & #", N, Spec_Id);
         end if;
      end if;

      --  A subprogram body freezes its own contract. Analyze the contract
      --  after the declarations of the body have been processed as pragmas
      --  are now chained on the contract of the subprogram body.

      Analyze_Entry_Or_Subprogram_Body_Contract (Body_Id);

      --  Check completion, and analyze the statements

      Check_Completion;
      Inspect_Deferred_Constant_Completion (Declarations (N));
      Analyze (HSS);

      --  Add the generated minimum accessibility objects to the subprogram
      --  body's list of declarations after analysis of the statements and
      --  contracts.

      while Is_Non_Empty_List (Minimum_Acc_Objs) loop
         if Present (Declarations (Body_Nod)) then
            Prepend (Remove_Head (Minimum_Acc_Objs), Declarations (Body_Nod));
         else
            Set_Declarations
              (Body_Nod, New_List (Remove_Head (Minimum_Acc_Objs)));
         end if;
      end loop;

      --  Deal with end of scope processing for the body

      Process_End_Label (HSS, 't', Current_Scope);
      Update_Use_Clause_Chain;
      End_Scope;

      --  If we are compiling an entry wrapper, remove the enclosing
      --  synchronized object from the stack.

      if Is_Entry_Wrapper (Body_Id) then
         End_Scope;
      end if;

      Check_Subprogram_Order (N);
      Set_Analyzed (Body_Id);

      --  If we have a separate spec, then the analysis of the declarations
      --  caused the entities in the body to be chained to the spec id, but
      --  we want them chained to the body id. Only the formal parameters
      --  end up chained to the spec id in this case.

      if Present (Spec_Id) then

         --  We must conform to the categorization of our spec

         Validate_Categorization_Dependency (N, Spec_Id);

         --  And if this is a child unit, the parent units must conform

         if Is_Child_Unit (Spec_Id) then
            Validate_Categorization_Dependency
              (Unit_Declaration_Node (Spec_Id), Spec_Id);
         end if;

         --  Here is where we move entities from the spec to the body

         --  Case where there are entities that stay with the spec

         if Present (Last_Real_Spec_Entity) then

            --  No body entities (happens when the only real spec entities come
            --  from precondition and postcondition pragmas).

            if No (Last_Entity (Body_Id)) then
               Set_First_Entity (Body_Id, Next_Entity (Last_Real_Spec_Entity));

            --  Body entities present (formals), so chain stuff past them

            else
               Link_Entities
                 (Last_Entity (Body_Id), Next_Entity (Last_Real_Spec_Entity));
            end if;

            Set_Next_Entity (Last_Real_Spec_Entity, Empty);
            Set_Last_Entity (Body_Id, Last_Entity (Spec_Id));
            Set_Last_Entity (Spec_Id, Last_Real_Spec_Entity);

         --  Case where there are no spec entities, in this case there can be
         --  no body entities either, so just move everything.

         --  If the body is generated for an expression function, it may have
         --  been preanalyzed already, if 'access was applied to it.

         else
            if Nkind (Original_Node (Unit_Declaration_Node (Spec_Id))) /=
                                                       N_Expression_Function
            then
               pragma Assert (No (Last_Entity (Body_Id)));
               null;
            end if;

            Set_First_Entity (Body_Id, First_Entity (Spec_Id));
            Set_Last_Entity  (Body_Id, Last_Entity (Spec_Id));
            Set_First_Entity (Spec_Id, Empty);
            Set_Last_Entity  (Spec_Id, Empty);
         end if;

      --  Otherwise the body does not complete a previous declaration. Check
      --  the categorization of the body against the units it withs.

      else
         Validate_Categorization_Dependency (N, Body_Id);
      end if;

      Check_Missing_Return;

      --  Now we are going to check for variables that are never modified in
      --  the body of the procedure. But first we deal with a special case
      --  where we want to modify this check. If the body of the subprogram
      --  starts with a raise statement or its equivalent, or if the body
      --  consists entirely of a null statement, then it is pretty obvious that
      --  it is OK to not reference the parameters. For example, this might be
      --  the following common idiom for a stubbed function: statement of the
      --  procedure raises an exception. In particular this deals with the
      --  common idiom of a stubbed function, which appears something like:

      --     function F (A : Integer) return Some_Type;
      --        X : Some_Type;
      --     begin
      --        raise Program_Error;
      --        return X;
      --     end F;

      --  Here the purpose of X is simply to satisfy the annoying requirement
      --  in Ada that there be at least one return, and we certainly do not
      --  want to go posting warnings on X that it is not initialized. On
      --  the other hand, if X is entirely unreferenced that should still
      --  get a warning.

      --  What we do is to detect these cases, and if we find them, flag the
      --  subprogram as being Is_Trivial_Subprogram and then use that flag to
      --  suppress unwanted warnings. For the case of the function stub above
      --  we have a special test to set X as apparently assigned to suppress
      --  the warning.

      declare
         Stm : Node_Id;

      begin
         --  Skip call markers installed by the ABE mechanism, labels, and
         --  Push_xxx_Error_Label to find the first real statement.

         Stm := First (Statements (HSS));
         while Nkind (Stm) in N_Call_Marker | N_Label | N_Push_xxx_Label loop
            Next (Stm);
         end loop;

         --  Do the test on the original statement before expansion

         declare
            Ostm : constant Node_Id := Original_Node (Stm);

         begin
            --  If explicit raise statement, turn on flag

            if Nkind (Ostm) = N_Raise_Statement then
               Set_Trivial_Subprogram (Stm);

            --  If null statement, and no following statements, turn on flag

            elsif Nkind (Stm) = N_Null_Statement
              and then Comes_From_Source (Stm)
              and then No (Next (Stm))
            then
               Set_Trivial_Subprogram (Stm);

            --  Check for explicit call cases which likely raise an exception

            elsif Nkind (Ostm) = N_Procedure_Call_Statement then
               if Is_Entity_Name (Name (Ostm)) then
                  declare
                     Ent : constant Entity_Id := Entity (Name (Ostm));

                  begin
                     --  If the procedure is marked No_Return, then likely it
                     --  raises an exception, but in any case it is not coming
                     --  back here, so turn on the flag.

                     if Present (Ent)
                       and then Ekind (Ent) = E_Procedure
                       and then No_Return (Ent)
                     then
                        Set_Trivial_Subprogram (Stm);
                     end if;
                  end;
               end if;
            end if;
         end;
      end;

      --  Check for variables that are never modified

      declare
         E1 : Entity_Id;
         E2 : Entity_Id;

      begin
         --  If there is a separate spec, then transfer Never_Set_In_Source
         --  flags from out parameters to the corresponding entities in the
         --  body. The reason we do that is we want to post error flags on
         --  the body entities, not the spec entities.

         if Present (Spec_Id) then
            E1 := First_Entity (Spec_Id);
            while Present (E1) loop
               if Ekind (E1) = E_Out_Parameter then
                  E2 := First_Entity (Body_Id);
                  while Present (E2) loop
                     exit when Chars (E1) = Chars (E2);
                     Next_Entity (E2);
                  end loop;

                  if Present (E2) then
                     Set_Never_Set_In_Source (E2, Never_Set_In_Source (E1));
                  end if;
               end if;

               Next_Entity (E1);
            end loop;
         end if;

         --  Check references of the subprogram spec when we are dealing with
         --  an expression function due to it having a generated body.
         --  Otherwise, we simply check the formals of the subprogram body.

         if Present (Spec_Id)
           and then Is_Expression_Function (Spec_Id)
         then
            Check_References (Spec_Id);
         else
            Check_References (Body_Id);
         end if;
      end;

      --  Check for nested subprogram, and mark outer level subprogram if so

      declare
         Ent : Entity_Id;

      begin
         if Present (Spec_Id) then
            Ent := Spec_Id;
         else
            Ent := Body_Id;
         end if;

         loop
            Ent := Enclosing_Subprogram (Ent);
            exit when No (Ent) or else Is_Subprogram (Ent);
         end loop;

         if Present (Ent) then
            Set_Has_Nested_Subprogram (Ent);
         end if;
      end;

      --  Restore the limited views in the spec, if any, to let the back end
      --  process it without running into circularities.

      if Exch_Views /= No_Elist then
         Restore_Limited_Views (Exch_Views);
      end if;

      if Mask_Types /= No_Elist then
         Unmask_Unfrozen_Types (Mask_Types);
      end if;

      if Present (Desig_View) then
         Set_Directly_Designated_Type (Etype (Spec_Id), Desig_View);
      end if;

   <<Leave>>
      if Present (Ignored_Ghost_Region) then
         Expander_Active := Saved_EA;
      end if;

      Ignore_SPARK_Mode_Pragmas_In_Instance := Saved_ISMP;
      Restore_Ghost_Region (Saved_GM, Saved_IGR);
   end Analyze_Subprogram_Body_Helper;

   ------------------------------------
   -- Analyze_Subprogram_Declaration --
   ------------------------------------

   procedure Analyze_Subprogram_Declaration (N : Node_Id) is
      Scop       : constant Entity_Id := Current_Scope;
      Designator : Entity_Id;

      Is_Completion : Boolean;
      --  Indicates whether a null procedure declaration is a completion

   begin
      --  Null procedures are not allowed in SPARK

      if Nkind (Specification (N)) = N_Procedure_Specification
        and then Null_Present (Specification (N))
      then
         --  Null procedures are allowed in protected types, following the
         --  recent AI12-0147.

         if Is_Protected_Type (Current_Scope)
           and then Ada_Version < Ada_2012
         then
            Error_Msg_N ("protected operation cannot be a null procedure", N);
         end if;

         Analyze_Null_Procedure (N, Is_Completion);

         --  The null procedure acts as a body, nothing further is needed

         if Is_Completion then
            return;
         end if;
      end if;

      Designator := Analyze_Subprogram_Specification (Specification (N));

      --  A reference may already have been generated for the unit name, in
      --  which case the following call is redundant. However it is needed for
      --  declarations that are the rewriting of an expression function.

      Generate_Definition (Designator);

      --  Set the SPARK mode from the current context (may be overwritten later
      --  with explicit pragma). This is not done for entry barrier functions
      --  because they are generated outside the protected type and should not
      --  carry the mode of the enclosing context.

      if Nkind (N) = N_Subprogram_Declaration
        and then Is_Entry_Barrier_Function (N)
      then
         null;

      else
         Set_SPARK_Pragma           (Designator, SPARK_Mode_Pragma);
         Set_SPARK_Pragma_Inherited (Designator);
      end if;

      --  Save the state of flag Ignore_SPARK_Mode_Pragmas_In_Instance in case
      --  the body of this subprogram is instantiated or inlined later and out
      --  of context. The body uses this attribute to restore the value of the
      --  global flag.

      if Ignore_SPARK_Mode_Pragmas_In_Instance then
         Set_Ignore_SPARK_Mode_Pragmas (Designator);
      end if;

      --  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     => Designator,
         Checks   => True,
         Warnings => True);

      if Debug_Flag_C then
         Write_Str ("==> subprogram spec ");
         Write_Name (Chars (Designator));
         Write_Str (" from ");
         Write_Location (Sloc (N));
         Write_Eol;
         Indent;
      end if;

      Validate_RCI_Subprogram_Declaration (N);
      New_Overloaded_Entity (Designator);
      Check_Delayed_Subprogram (Designator);

      --  If the type of the first formal of the current subprogram is a non-
      --  generic tagged private type, mark the subprogram as being a private
      --  primitive. Ditto if this is a function with controlling result, and
      --  the return type is currently private. In both cases, the type of the
      --  controlling argument or result must be in the current scope for the
      --  operation to be primitive.

      if Has_Controlling_Result (Designator)
        and then Is_Private_Type (Etype (Designator))
        and then Scope (Etype (Designator)) = Current_Scope
        and then not Is_Generic_Actual_Type (Etype (Designator))
      then
         Set_Is_Private_Primitive (Designator);

      elsif Present (First_Formal (Designator)) then
         declare
            Formal_Typ : constant Entity_Id :=
                           Etype (First_Formal (Designator));
         begin
            Set_Is_Private_Primitive (Designator,
              Is_Tagged_Type (Formal_Typ)
                and then Scope (Formal_Typ) = Current_Scope
                and then Is_Private_Type (Formal_Typ)
                and then not Is_Generic_Actual_Type (Formal_Typ));
         end;
      end if;

      --  Ada 2005 (AI-251): Abstract interface primitives must be abstract
      --  or null.

      if Ada_Version >= Ada_2005
        and then Comes_From_Source (N)
        and then Is_Dispatching_Operation (Designator)
      then
         declare
            E    : Entity_Id;
            Etyp : Entity_Id;

         begin
            if Has_Controlling_Result (Designator) then
               Etyp := Etype (Designator);

            else
               E := First_Entity (Designator);
               while Present (E)
                 and then Is_Formal (E)
                 and then not Is_Controlling_Formal (E)
               loop
                  Next_Entity (E);
               end loop;

               Etyp := Etype (E);
            end if;

            if Is_Access_Type (Etyp) then
               Etyp := Directly_Designated_Type (Etyp);
            end if;

            if Is_Interface (Etyp)
              and then not Is_Abstract_Subprogram (Designator)
              and then not (Ekind (Designator) = E_Procedure
                             and then Null_Present (Specification (N)))
            then
               Error_Msg_Name_1 := Chars (Defining_Entity (N));

               --  Specialize error message based on procedures vs. functions,
               --  since functions can't be null subprograms.

               if Ekind (Designator) = E_Procedure then
                  Error_Msg_N
                    ("interface procedure % must be abstract or null", N);
               else
                  Error_Msg_N
                    ("interface function % must be abstract", N);
               end if;
            end if;
         end;
      end if;

      --  What is the following code for, it used to be

      --  ???   Set_Suppress_Elaboration_Checks
      --  ???     (Designator, Elaboration_Checks_Suppressed (Designator));

      --  The following seems equivalent, but a bit dubious

      if Elaboration_Checks_Suppressed (Designator) then
         Set_Kill_Elaboration_Checks (Designator);
      end if;

      --  For a compilation unit, set body required. This flag will only be
      --  reset if a valid Import or Interface pragma is processed later on.

      if Nkind (Parent (N)) = N_Compilation_Unit then
         Set_Body_Required (Parent (N), True);

         if Ada_Version >= Ada_2005
           and then Nkind (Specification (N)) = N_Procedure_Specification
           and then Null_Present (Specification (N))
         then
            Error_Msg_N
              ("null procedure cannot be declared at library level", N);
         end if;
      end if;

      Generate_Reference_To_Formals (Designator);
      Check_Eliminated (Designator);

      if Debug_Flag_C then
         Outdent;
         Write_Str ("<== subprogram spec ");
         Write_Name (Chars (Designator));
         Write_Str (" from ");
         Write_Location (Sloc (N));
         Write_Eol;
      end if;

      --  Indicate that this is a protected operation, because it may be used
      --  in subsequent declarations within the protected type.

      if Is_Protected_Type (Current_Scope) then
         Set_Convention (Designator, Convention_Protected);
      end if;

      List_Inherited_Pre_Post_Aspects (Designator);

      --  Process the aspects before establishing the proper categorization in
      --  case the subprogram is a compilation unit and one of its aspects is
      --  converted into a categorization pragma.

      if Has_Aspects (N) then
         Analyze_Aspect_Specifications (N, Designator);
      end if;

      if Scop /= Standard_Standard and then not Is_Child_Unit (Designator) then
         Set_Categorization_From_Scope (Designator, Scop);

      --  Otherwise the unit is a compilation unit and/or a child unit. Set the
      --  proper categorization of the unit based on its pragmas.

      else
         Push_Scope (Designator);
         Set_Categorization_From_Pragmas (N);
         Validate_Categorization_Dependency (N, Designator);
         Pop_Scope;
      end if;
   end Analyze_Subprogram_Declaration;

   --------------------------------------
   -- Analyze_Subprogram_Specification --
   --------------------------------------

   --  Reminder: N here really is a subprogram specification (not a subprogram
   --  declaration). This procedure is called to analyze the specification in
   --  both subprogram bodies and subprogram declarations (specs).

   function Analyze_Subprogram_Specification (N : Node_Id) return Entity_Id is
      function Is_Invariant_Procedure_Or_Body (E : Entity_Id) return Boolean;
      --  Determine whether entity E denotes the spec or body of an invariant
      --  procedure.

      ------------------------------------
      -- Is_Invariant_Procedure_Or_Body --
      ------------------------------------

      function Is_Invariant_Procedure_Or_Body (E : Entity_Id) return Boolean is
         Decl : constant Node_Id := Unit_Declaration_Node (E);
         Spec : Entity_Id;

      begin
         if Nkind (Decl) = N_Subprogram_Body then
            Spec := Corresponding_Spec (Decl);
         else
            Spec := E;
         end if;

         return
           Present (Spec)
             and then Ekind (Spec) = E_Procedure
             and then (Is_Partial_Invariant_Procedure (Spec)
                        or else Is_Invariant_Procedure (Spec));
      end Is_Invariant_Procedure_Or_Body;

      --  Local variables

      Designator : constant Entity_Id := Defining_Entity (N);
      Formals    : constant List_Id   := Parameter_Specifications (N);

   --  Start of processing for Analyze_Subprogram_Specification

   begin
      --  Proceed with analysis. Do not emit a cross-reference entry if the
      --  specification comes from an expression function, because it may be
      --  the completion of a previous declaration. If it is not, the cross-
      --  reference entry will be emitted for the new subprogram declaration.

      if Nkind (Parent (N)) /= N_Expression_Function then
         Generate_Definition (Designator);
      end if;

      if Nkind (N) = N_Function_Specification then
         Mutate_Ekind (Designator, E_Function);
         Set_Mechanism (Designator, Default_Mechanism);
      else
         Mutate_Ekind (Designator, E_Procedure);
         Set_Etype (Designator, Standard_Void_Type);
      end if;

      --  Flag Is_Inlined_Always is True by default, and reversed to False for
      --  those subprograms which could be inlined in GNATprove mode (because
      --  Body_To_Inline is non-Empty) but should not be inlined.

      if GNATprove_Mode then
         Set_Is_Inlined_Always (Designator);
      end if;

      --  Introduce new scope for analysis of the formals and the return type

      Set_Scope (Designator, Current_Scope);

      if Present (Formals) then
         Push_Scope (Designator);
         Process_Formals (Formals, N);

         --  Check dimensions in N for formals with default expression

         Analyze_Dimension_Formals (N, Formals);

         --  Ada 2005 (AI-345): If this is an overriding operation of an
         --  inherited interface operation, and the controlling type is
         --  a synchronized type, replace the type with its corresponding
         --  record, to match the proper signature of an overriding operation.
         --  Same processing for an access parameter whose designated type is
         --  derived from a synchronized interface.

         --  This modification is not done for invariant procedures because
         --  the corresponding record may not necessarely be visible when the
         --  concurrent type acts as the full view of a private type.

         --    package Pack is
         --       type Prot is private with Type_Invariant => ...;
         --       procedure ConcInvariant (Obj : Prot);
         --    private
         --       protected type Prot is ...;
         --       type Concurrent_Record_Prot is record ...;
         --       procedure ConcInvariant (Obj : Prot) is
         --          ...
         --       end ConcInvariant;
         --    end Pack;

         --  In the example above, both the spec and body of the invariant
         --  procedure must utilize the private type as the controlling type.

         if Ada_Version >= Ada_2005
           and then not Is_Invariant_Procedure_Or_Body (Designator)
         then
            declare
               Formal     : Entity_Id;
               Formal_Typ : Entity_Id;
               Rec_Typ    : Entity_Id;
               Desig_Typ  : Entity_Id;

            begin
               Formal := First_Formal (Designator);
               while Present (Formal) loop
                  Formal_Typ := Etype (Formal);

                  if Is_Concurrent_Type (Formal_Typ)
                    and then Present (Corresponding_Record_Type (Formal_Typ))
                  then
                     Rec_Typ := Corresponding_Record_Type (Formal_Typ);

                     if Present (Interfaces (Rec_Typ)) then
                        Set_Etype (Formal, Rec_Typ);
                     end if;

                  elsif Ekind (Formal_Typ) = E_Anonymous_Access_Type then
                     Desig_Typ := Designated_Type (Formal_Typ);

                     if Is_Concurrent_Type (Desig_Typ)
                       and then Present (Corresponding_Record_Type (Desig_Typ))
                     then
                        Rec_Typ := Corresponding_Record_Type (Desig_Typ);

                        if Present (Interfaces (Rec_Typ)) then
                           Set_Directly_Designated_Type (Formal_Typ, Rec_Typ);
                        end if;
                     end if;
                  end if;

                  Next_Formal (Formal);
               end loop;
            end;
         end if;

         End_Scope;

      --  The subprogram scope is pushed and popped around the processing of
      --  the return type for consistency with call above to Process_Formals
      --  (which itself can call Analyze_Return_Type), and to ensure that any
      --  itype created for the return type will be associated with the proper
      --  scope.

      elsif Nkind (N) = N_Function_Specification then
         Push_Scope (Designator);
         Analyze_Return_Type (N);
         End_Scope;
      end if;

      --  Function case

      if Nkind (N) = N_Function_Specification then

         --  Deal with operator symbol case

         if Nkind (Designator) = N_Defining_Operator_Symbol then
            Valid_Operator_Definition (Designator);
         end if;

         May_Need_Actuals (Designator);

         --  Ada 2005 (AI-251): If the return type is abstract, verify that
         --  the subprogram is abstract also. This does not apply to renaming
         --  declarations, where abstractness is inherited, and to subprogram
         --  bodies generated for stream operations, which become renamings as
         --  bodies.

         --  In case of primitives associated with abstract interface types
         --  the check is applied later (see Analyze_Subprogram_Declaration).

         if Nkind (Original_Node (Parent (N))) not in
              N_Abstract_Subprogram_Declaration        |
              N_Formal_Abstract_Subprogram_Declaration |
              N_Subprogram_Renaming_Declaration
         then
            if Is_Abstract_Type (Etype (Designator)) then
               Error_Msg_N
                 ("function that returns abstract type must be abstract", N);

            --  Ada 2012 (AI-0073): Extend this test to subprograms with an
            --  access result whose designated type is abstract.

            elsif Ada_Version >= Ada_2012
              and then Nkind (Result_Definition (N)) = N_Access_Definition
              and then
                not Is_Class_Wide_Type (Designated_Type (Etype (Designator)))
              and then Is_Abstract_Type (Designated_Type (Etype (Designator)))
            then
               Error_Msg_N
                 ("function whose access result designates abstract type "
                  & "must be abstract", N);
            end if;
         end if;
      end if;

      return Designator;
   end Analyze_Subprogram_Specification;

   -----------------------
   -- Check_Conformance --
   -----------------------

   procedure Check_Conformance
     (New_Id                   : Entity_Id;
      Old_Id                   : Entity_Id;
      Ctype                    : Conformance_Type;
      Errmsg                   : Boolean;
      Conforms                 : out Boolean;
      Err_Loc                  : Node_Id := Empty;
      Get_Inst                 : Boolean := False;
      Skip_Controlling_Formals : Boolean := False)
   is
      procedure Conformance_Error (Msg : String; N : Node_Id := New_Id);
      --  Sets Conforms to False. If Errmsg is False, then that's all it does.
      --  If Errmsg is True, then processing continues to post an error message
      --  for conformance error on given node. Two messages are output. The
      --  first message points to the previous declaration with a general "no
      --  conformance" message. The second is the detailed reason, supplied as
      --  Msg. The parameter N provide information for a possible & insertion
      --  in the message, and also provides the location for posting the
      --  message in the absence of a specified Err_Loc location.

      function Conventions_Match (Id1, Id2 : Entity_Id) return Boolean;
      --  True if the conventions of entities Id1 and Id2 match.

      function Null_Exclusions_Match (F1, F2 : Entity_Id) return Boolean;
      --  True if the null exclusions of two formals of anonymous access type
      --  match.

      -----------------------
      -- Conformance_Error --
      -----------------------

      procedure Conformance_Error (Msg : String; N : Node_Id := New_Id) is
         Enode : Node_Id;

      begin
         Conforms := False;

         if Errmsg then
            if No (Err_Loc) then
               Enode := N;
            else
               Enode := Err_Loc;
            end if;

            Error_Msg_Sloc := Sloc (Old_Id);

            case Ctype is
               when Type_Conformant =>
                  Error_Msg_N -- CODEFIX
                    ("not type conformant with declaration#!", Enode);

               when Mode_Conformant =>
                  if Nkind (Parent (Old_Id)) = N_Full_Type_Declaration then
                     Error_Msg_N
                       ("not mode conformant with operation inherited#!",
                         Enode);
                  else
                     Error_Msg_N
                       ("not mode conformant with declaration#!", Enode);
                  end if;

               when Subtype_Conformant =>
                  if Nkind (Parent (Old_Id)) = N_Full_Type_Declaration then
                     Error_Msg_N
                       ("not subtype conformant with operation inherited#!",
                         Enode);
                  else
                     Error_Msg_N
                       ("not subtype conformant with declaration#!", Enode);
                  end if;

               when Fully_Conformant =>
                  if Nkind (Parent (Old_Id)) = N_Full_Type_Declaration then
                     Error_Msg_N -- CODEFIX
                       ("not fully conformant with operation inherited#!",
                         Enode);
                  else
                     Error_Msg_N -- CODEFIX
                       ("not fully conformant with declaration#!", Enode);
                  end if;
            end case;

            Error_Msg_NE (Msg, Enode, N);
         end if;
      end Conformance_Error;

      -----------------------
      -- Conventions_Match --
      -----------------------

      function Conventions_Match
        (Id1 : Entity_Id;
         Id2 : Entity_Id) return Boolean
      is
      begin
         --  Ignore the conventions of anonymous access-to-subprogram types
         --  and subprogram types because these are internally generated and
         --  the only way these may receive a convention is if they inherit
         --  the convention of a related subprogram.

         if Ekind (Id1) in E_Anonymous_Access_Subprogram_Type
                         | E_Subprogram_Type
              or else
            Ekind (Id2) in E_Anonymous_Access_Subprogram_Type
                         | E_Subprogram_Type
         then
            return True;

         --  Otherwise compare the conventions directly

         else
            return Convention (Id1) = Convention (Id2);
         end if;
      end Conventions_Match;

      ---------------------------
      -- Null_Exclusions_Match --
      ---------------------------

      function Null_Exclusions_Match (F1, F2 : Entity_Id) return Boolean is
      begin
         if not Is_Anonymous_Access_Type (Etype (F1))
           or else not Is_Anonymous_Access_Type (Etype (F2))
         then
            return True;
         end if;

         --  AI12-0289-1: Case of controlling access parameter; False if the
         --  partial view is untagged, the full view is tagged, and no explicit
         --  "not null". Note that at this point, we're processing the package
         --  body, so private/full types have been swapped. The Sloc test below
         --  is to detect the (legal) case where F1 comes after the full type
         --  declaration. This part is disabled pre-2005, because "not null" is
         --  not allowed on those language versions.

         if Ada_Version >= Ada_2005
           and then Is_Controlling_Formal (F1)
           and then not Null_Exclusion_Present (Parent (F1))
           and then not Null_Exclusion_Present (Parent (F2))
         then
            declare
               D : constant Entity_Id := Directly_Designated_Type (Etype (F1));
               Partial_View_Of_Desig : constant Entity_Id :=
                 Incomplete_Or_Partial_View (D);
            begin
               return No (Partial_View_Of_Desig)
                 or else Is_Tagged_Type (Partial_View_Of_Desig)
                 or else Sloc (D) < Sloc (F1);
            end;

         --  Not a controlling parameter, or one or both views have an explicit
         --  "not null".

         else
            return Null_Exclusion_Present (Parent (F1)) =
                   Null_Exclusion_Present (Parent (F2));
         end if;
      end Null_Exclusions_Match;

      --  Local Variables

      Old_Type           : constant Entity_Id := Etype (Old_Id);
      New_Type           : constant Entity_Id := Etype (New_Id);
      Old_Formal         : Entity_Id;
      New_Formal         : Entity_Id;
      Old_Formal_Base    : Entity_Id;
      New_Formal_Base    : Entity_Id;

   --  Start of processing for Check_Conformance

   begin
      Conforms := True;

      --  We need a special case for operators, since they don't appear
      --  explicitly.

      if Ctype = Type_Conformant then
         if Ekind (New_Id) = E_Operator
           and then Operator_Matches_Spec (New_Id, Old_Id)
         then
            return;
         end if;
      end if;

      --  If both are functions/operators, check return types conform

      if Old_Type /= Standard_Void_Type
           and then
         New_Type /= Standard_Void_Type
      then
         --  If we are checking interface conformance we omit controlling
         --  arguments and result, because we are only checking the conformance
         --  of the remaining parameters.

         if Has_Controlling_Result (Old_Id)
           and then Has_Controlling_Result (New_Id)
           and then Skip_Controlling_Formals
         then
            null;

         elsif not Conforming_Types (Old_Type, New_Type, Ctype, Get_Inst) then
            if Ctype >= Subtype_Conformant
              and then not Predicates_Match (Old_Type, New_Type)
            then
               Conformance_Error
                 ("\predicate of return type does not match!", New_Id);
            else
               Conformance_Error
                 ("\return type does not match!", New_Id);
            end if;

            return;
         end if;

         --  Ada 2005 (AI-231): In case of anonymous access types check the
         --  null-exclusion and access-to-constant attributes match.

         if Ada_Version >= Ada_2005
           and then Ekind (Etype (Old_Type)) = E_Anonymous_Access_Type
           and then
             (Can_Never_Be_Null (Old_Type) /= Can_Never_Be_Null (New_Type)
               or else Is_Access_Constant (Etype (Old_Type)) /=
                       Is_Access_Constant (Etype (New_Type)))
         then
            Conformance_Error ("\return type does not match!", New_Id);
            return;
         end if;

      --  If either is a function/operator and the other isn't, error

      elsif Old_Type /= Standard_Void_Type
        or else New_Type /= Standard_Void_Type
      then
         Conformance_Error ("\functions can only match functions!", New_Id);
         return;
      end if;

      --  In subtype conformant case, conventions must match (RM 6.3.1(16)).
      --  If this is a renaming as body, refine error message to indicate that
      --  the conflict is with the original declaration. If the entity is not
      --  frozen, the conventions don't have to match, the one of the renamed
      --  entity is inherited.

      if Ctype >= Subtype_Conformant then
         if not Conventions_Match (Old_Id, New_Id) then
            if not Is_Frozen (New_Id) then
               null;

            elsif Present (Err_Loc)
              and then Nkind (Err_Loc) = N_Subprogram_Renaming_Declaration
              and then Present (Corresponding_Spec (Err_Loc))
            then
               Error_Msg_Name_1 := Chars (New_Id);
               Error_Msg_Name_2 :=
                 Name_Ada + Convention_Id'Pos (Convention (New_Id));
               Conformance_Error ("\prior declaration for% has convention %!");
               return;

            else
               Conformance_Error ("\calling conventions do not match!");
               return;
            end if;
         else
            Check_Formal_Subprogram_Conformance
              (New_Id, Old_Id, Err_Loc, Errmsg, Conforms);

            if not Conforms then
               return;
            end if;
         end if;
      end if;

      --  Deal with parameters

      --  Note: we use the entity information, rather than going directly
      --  to the specification in the tree. This is not only simpler, but
      --  absolutely necessary for some cases of conformance tests between
      --  operators, where the declaration tree simply does not exist.

      Old_Formal := First_Formal (Old_Id);
      New_Formal := First_Formal (New_Id);
      while Present (Old_Formal) and then Present (New_Formal) loop
         if Is_Controlling_Formal (Old_Formal)
           and then Is_Controlling_Formal (New_Formal)
           and then Skip_Controlling_Formals
         then
            --  The controlling formals will have different types when
            --  comparing an interface operation with its match, but both
            --  or neither must be access parameters.

            if Is_Access_Type (Etype (Old_Formal))
                 =
               Is_Access_Type (Etype (New_Formal))
            then
               goto Skip_Controlling_Formal;
            else
               Conformance_Error
                 ("\access parameter does not match!", New_Formal);
            end if;
         end if;

         --  Ada 2012: Mode conformance also requires that formal parameters
         --  be both aliased, or neither.

         if Ctype >= Mode_Conformant and then Ada_Version >= Ada_2012 then
            if Is_Aliased (Old_Formal) /= Is_Aliased (New_Formal) then
               Conformance_Error
                 ("\aliased parameter mismatch!", New_Formal);
            end if;
         end if;

         if Ctype = Fully_Conformant then

            --  Names must match. Error message is more accurate if we do
            --  this before checking that the types of the formals match.

            if Chars (Old_Formal) /= Chars (New_Formal) then
               Conformance_Error ("\name& does not match!", New_Formal);

               --  Set error posted flag on new formal as well to stop
               --  junk cascaded messages in some cases.

               Set_Error_Posted (New_Formal);
               return;
            end if;

            --  Null exclusion must match

            if not Null_Exclusions_Match (Old_Formal, New_Formal) then
               Conformance_Error
                 ("\null exclusion for& does not match", New_Formal);

               --  Mark error posted on the new formal to avoid duplicated
               --  complaint about types not matching.

               Set_Error_Posted (New_Formal);
            end if;
         end if;

         --  Ada 2005 (AI-423): Possible access [sub]type and itype match. This
         --  case occurs whenever a subprogram is being renamed and one of its
         --  parameters imposes a null exclusion. For example:

         --     type T is null record;
         --     type Acc_T is access T;
         --     subtype Acc_T_Sub is Acc_T;

         --     procedure P     (Obj : not null Acc_T_Sub);  --  itype
         --     procedure Ren_P (Obj :          Acc_T_Sub)   --  subtype
         --       renames P;

         Old_Formal_Base := Etype (Old_Formal);
         New_Formal_Base := Etype (New_Formal);

         if Get_Inst then
            Old_Formal_Base := Get_Instance_Of (Old_Formal_Base);
            New_Formal_Base := Get_Instance_Of (New_Formal_Base);
         end if;

         --  Types must always match. In the visible part of an instance,
         --  usual overloading rules for dispatching operations apply, and
         --  we check base types (not the actual subtypes).

         if In_Instance_Visible_Part
           and then Is_Dispatching_Operation (New_Id)
         then
            if not Conforming_Types
                     (T1       => Base_Type (Etype (Old_Formal)),
                      T2       => Base_Type (Etype (New_Formal)),
                      Ctype    => Ctype,
                      Get_Inst => Get_Inst)
            then
               Conformance_Error ("\type of & does not match!", New_Formal);
               return;
            end if;

         elsif not Conforming_Types
                     (T1       => Old_Formal_Base,
                      T2       => New_Formal_Base,
                      Ctype    => Ctype,
                      Get_Inst => Get_Inst)
         then
            --  Don't give error message if old type is Any_Type. This test
            --  avoids some cascaded errors, e.g. in case of a bad spec.

            if Errmsg and then Old_Formal_Base = Any_Type then
               Conforms := False;
            else
               if Ctype >= Subtype_Conformant
                 and then
                   not Predicates_Match (Old_Formal_Base, New_Formal_Base)
               then
                  Conformance_Error
                    ("\predicate of & does not match!", New_Formal);
               else
                  Conformance_Error
                    ("\type of & does not match!", New_Formal);

                  if not Dimensions_Match (Old_Formal_Base, New_Formal_Base)
                  then
                     Error_Msg_N ("\dimensions mismatch!", New_Formal);
                  end if;
               end if;
            end if;

            return;
         end if;

         --  For mode conformance, mode must match

         if Ctype >= Mode_Conformant then
            if Parameter_Mode (Old_Formal) /= Parameter_Mode (New_Formal) then
               if Ekind (New_Id) not in E_Function | E_Procedure
                 or else not Is_Primitive_Wrapper (New_Id)
               then
                  Conformance_Error ("\mode of & does not match!", New_Formal);

               else
                  declare
                     T : constant Entity_Id := Find_Dispatching_Type (New_Id);
                  begin
                     if Is_Protected_Type (Corresponding_Concurrent_Type (T))
                     then
                        Conforms := False;

                        if Errmsg then
                           Error_Msg_PT (New_Id, Ultimate_Alias (Old_Id));
                        end if;
                     else
                        Conformance_Error
                          ("\mode of & does not match!", New_Formal);
                     end if;
                  end;
               end if;

               return;

            elsif Is_Access_Type (Old_Formal_Base)
              and then Is_Access_Type (New_Formal_Base)
              and then Is_Access_Constant (Old_Formal_Base) /=
                       Is_Access_Constant (New_Formal_Base)
            then
               Conformance_Error
                 ("\constant modifier does not match!", New_Formal);
               return;
            end if;
         end if;

         if Ctype >= Subtype_Conformant then

            --  Ada 2005 (AI-231): In case of anonymous access types check
            --  the null-exclusion and access-to-constant attributes must
            --  match. For null exclusion, we test the types rather than the
            --  formals themselves, since the attribute is only set reliably
            --  on the formals in the Ada 95 case, and we exclude the case
            --  where Old_Formal is marked as controlling, to avoid errors
            --  when matching completing bodies with dispatching declarations
            --  (access formals in the bodies aren't marked Can_Never_Be_Null).

            if Ada_Version >= Ada_2005
              and then Is_Anonymous_Access_Type (Etype (Old_Formal))
              and then Is_Anonymous_Access_Type (Etype (New_Formal))
              and then
                ((Can_Never_Be_Null (Etype (Old_Formal)) /=
                  Can_Never_Be_Null (Etype (New_Formal))
                    and then
                      not Is_Controlling_Formal (Old_Formal))
                   or else
                 Is_Access_Constant (Etype (Old_Formal)) /=
                 Is_Access_Constant (Etype (New_Formal)))

              --  Do not complain if error already posted on New_Formal. This
              --  avoids some redundant error messages.

              and then not Error_Posted (New_Formal)
            then
               --  It is allowed to omit the null-exclusion in case of stream
               --  attribute subprograms. We recognize stream subprograms
               --  through their TSS-generated suffix.

               declare
                  TSS_Name : constant TSS_Name_Type := Get_TSS_Name (New_Id);

               begin
                  if TSS_Name /= TSS_Stream_Read
                    and then TSS_Name /= TSS_Stream_Write
                    and then TSS_Name /= TSS_Stream_Input
                    and then TSS_Name /= TSS_Stream_Output
                  then
                     --  Here we have a definite conformance error. It is worth
                     --  special casing the error message for the case of a
                     --  controlling formal (which excludes null).

                     if Is_Controlling_Formal (New_Formal) then
                        Error_Msg_Node_2 := Scope (New_Formal);
                        Conformance_Error
                         ("\controlling formal & of & excludes null, "
                          & "declaration must exclude null as well",
                          New_Formal);

                     --  Normal case (couldn't we give more detail here???)

                     else
                        Conformance_Error
                          ("\type of & does not match!", New_Formal);
                     end if;

                     return;
                  end if;
               end;
            end if;
         end if;

         --  Full conformance checks

         if Ctype = Fully_Conformant then

            --  We have checked already that names match

            if Parameter_Mode (Old_Formal) = E_In_Parameter then

               --  Check default expressions for in parameters

               declare
                  NewD : constant Boolean :=
                           Present (Default_Value (New_Formal));
                  OldD : constant Boolean :=
                           Present (Default_Value (Old_Formal));
               begin
                  if NewD or OldD then

                     --  The old default value has been analyzed because the
                     --  current full declaration will have frozen everything
                     --  before. The new default value has not been analyzed,
                     --  so analyze it now before we check for conformance.

                     if NewD then
                        Push_Scope (New_Id);
                        Preanalyze_Spec_Expression
                          (Default_Value (New_Formal), Etype (New_Formal));
                        End_Scope;
                     end if;

                     if not (NewD and OldD)
                       or else not Fully_Conformant_Expressions
                                    (Default_Value (Old_Formal),
                                     Default_Value (New_Formal))
                     then
                        Conformance_Error
                          ("\default expression for & does not match!",
                           New_Formal);
                        return;
                     end if;
                  end if;
               end;
            end if;
         end if;

         --  A couple of special checks for Ada 83 mode. These checks are
         --  skipped if either entity is an operator in package Standard,
         --  or if either old or new instance is not from the source program.

         if Ada_Version = Ada_83
           and then Sloc (Old_Id) > Standard_Location
           and then Sloc (New_Id) > Standard_Location
           and then Comes_From_Source (Old_Id)
           and then Comes_From_Source (New_Id)
         then
            declare
               Old_Param : constant Node_Id := Declaration_Node (Old_Formal);
               New_Param : constant Node_Id := Declaration_Node (New_Formal);

            begin
               --  Explicit IN must be present or absent in both cases. This
               --  test is required only in the full conformance case.

               if In_Present (Old_Param) /= In_Present (New_Param)
                 and then Ctype = Fully_Conformant
               then
                  Conformance_Error
                    ("\(Ada 83) IN must appear in both declarations",
                     New_Formal);
                  return;
               end if;

               --  Grouping (use of comma in param lists) must be the same
               --  This is where we catch a misconformance like:

               --    A, B : Integer
               --    A : Integer; B : Integer

               --  which are represented identically in the tree except
               --  for the setting of the flags More_Ids and Prev_Ids.

               if More_Ids (Old_Param) /= More_Ids (New_Param)
                 or else Prev_Ids (Old_Param) /= Prev_Ids (New_Param)
               then
                  Conformance_Error
                    ("\grouping of & does not match!", New_Formal);
                  return;
               end if;
            end;
         end if;

         --  This label is required when skipping controlling formals

         <<Skip_Controlling_Formal>>

         Next_Formal (Old_Formal);
         Next_Formal (New_Formal);
      end loop;

      if Present (Old_Formal) then
         Conformance_Error ("\too few parameters!");
         return;

      elsif Present (New_Formal) then
         Conformance_Error ("\too many parameters!", New_Formal);
         return;
      end if;
   end Check_Conformance;

   -----------------------
   -- Check_Conventions --
   -----------------------

   procedure Check_Conventions (Typ : Entity_Id) is
      Ifaces_List : Elist_Id;

      procedure Check_Convention (Op : Entity_Id);
      --  Verify that the convention of inherited dispatching operation Op is
      --  consistent among all subprograms it overrides. In order to minimize
      --  the search, Search_From is utilized to designate a specific point in
      --  the list rather than iterating over the whole list once more.

      ----------------------
      -- Check_Convention --
      ----------------------

      procedure Check_Convention (Op : Entity_Id) is
         Op_Conv         : constant Convention_Id := Convention (Op);
         Iface_Conv      : Convention_Id;
         Iface_Elmt      : Elmt_Id;
         Iface_Prim_Elmt : Elmt_Id;
         Iface_Prim      : Entity_Id;

      begin
         Iface_Elmt := First_Elmt (Ifaces_List);
         while Present (Iface_Elmt) loop
            Iface_Prim_Elmt :=
              First_Elmt (Primitive_Operations (Node (Iface_Elmt)));
            while Present (Iface_Prim_Elmt) loop
               Iface_Prim := Node (Iface_Prim_Elmt);
               Iface_Conv := Convention (Iface_Prim);

               if Is_Interface_Conformant (Typ, Iface_Prim, Op)
                 and then Iface_Conv /= Op_Conv
               then
                  Error_Msg_N
                    ("inconsistent conventions in primitive operations", Typ);

                  Error_Msg_Name_1 := Chars (Op);
                  Error_Msg_Name_2 := Get_Convention_Name (Op_Conv);
                  Error_Msg_Sloc   := Sloc (Op);

                  if Comes_From_Source (Op) or else No (Alias (Op)) then
                     if not Present (Overridden_Operation (Op)) then
                        Error_Msg_N ("\\primitive % defined #", Typ);
                     else
                        Error_Msg_N
                          ("\\overriding operation % with "
                           & "convention % defined #", Typ);
                     end if;

                  else pragma Assert (Present (Alias (Op)));
                     Error_Msg_Sloc := Sloc (Alias (Op));
                     Error_Msg_N ("\\inherited operation % with "
                                  & "convention % defined #", Typ);
                  end if;

                  Error_Msg_Name_1 := Chars (Op);
                  Error_Msg_Name_2 := Get_Convention_Name (Iface_Conv);
                  Error_Msg_Sloc   := Sloc (Iface_Prim);
                  Error_Msg_N ("\\overridden operation % with "
                               & "convention % defined #", Typ);

                  --  Avoid cascading errors

                  return;
               end if;

               Next_Elmt (Iface_Prim_Elmt);
            end loop;

            Next_Elmt (Iface_Elmt);
         end loop;
      end Check_Convention;

      --  Local variables

      Prim_Op      : Entity_Id;
      Prim_Op_Elmt : Elmt_Id;

   --  Start of processing for Check_Conventions

   begin
      if not Has_Interfaces (Typ) then
         return;
      end if;

      Collect_Interfaces (Typ, Ifaces_List);

      --  The algorithm checks every overriding dispatching operation against
      --  all the corresponding overridden dispatching operations, detecting
      --  differences in conventions.

      Prim_Op_Elmt := First_Elmt (Primitive_Operations (Typ));
      while Present (Prim_Op_Elmt) loop
         Prim_Op := Node (Prim_Op_Elmt);

         --  A small optimization: skip the predefined dispatching operations
         --  since they always have the same convention.

         if not Is_Predefined_Dispatching_Operation (Prim_Op) then
            Check_Convention (Prim_Op);
         end if;

         Next_Elmt (Prim_Op_Elmt);
      end loop;
   end Check_Conventions;

   ------------------------------
   -- Check_Delayed_Subprogram --
   ------------------------------

   procedure Check_Delayed_Subprogram (Designator : Entity_Id) is
      procedure Possible_Freeze (T : Entity_Id);
      --  T is the type of either a formal parameter or of the return type. If
      --  T is not yet frozen and needs a delayed freeze, then the subprogram
      --  itself must be delayed.

      ---------------------
      -- Possible_Freeze --
      ---------------------

      procedure Possible_Freeze (T : Entity_Id) is
         Scop : constant Entity_Id := Scope (Designator);

      begin
         --  If the subprogram appears within a package instance (which may be
         --  the wrapper package of a subprogram instance) the freeze node for
         --  that package will freeze the subprogram at the proper place, so
         --  do not emit a freeze node for the subprogram, given that it may
         --  appear in the wrong scope.

         if Ekind (Scop) = E_Package
           and then not Comes_From_Source (Scop)
           and then Is_Generic_Instance (Scop)
         then
            null;

         elsif Has_Delayed_Freeze (T) and then not Is_Frozen (T) then
            Set_Has_Delayed_Freeze (Designator);

         elsif Is_Access_Type (T)
           and then Has_Delayed_Freeze (Designated_Type (T))
           and then not Is_Frozen (Designated_Type (T))
         then
            Set_Has_Delayed_Freeze (Designator);
         end if;
      end Possible_Freeze;

      --  Local variables

      F : Entity_Id;

   --  Start of processing for Check_Delayed_Subprogram

   begin
      --  All subprograms, including abstract subprograms, may need a freeze
      --  node if some formal type or the return type needs one.

      Possible_Freeze (Etype (Designator));
      Possible_Freeze (Base_Type (Etype (Designator))); -- needed ???

      --  Need delayed freeze if any of the formal types themselves need a
      --  delayed freeze and are not yet frozen.

      F := First_Formal (Designator);
      while Present (F) loop
         Possible_Freeze (Etype (F));
         Possible_Freeze (Base_Type (Etype (F))); -- needed ???
         Next_Formal (F);
      end loop;

      --  Mark functions that return by reference. Note that it cannot be done
      --  for delayed_freeze subprograms because the underlying returned type
      --  may not be known yet (for private types).

      if not Has_Delayed_Freeze (Designator) and then Expander_Active then
         declare
            Typ  : constant Entity_Id := Etype (Designator);
            Utyp : constant Entity_Id := Underlying_Type (Typ);

         begin
            if Is_Limited_View (Typ) then
               Set_Returns_By_Ref (Designator);

            elsif Present (Utyp) and then CW_Or_Has_Controlled_Part (Utyp) then
               Set_Returns_By_Ref (Designator);
            end if;
         end;
      end if;
   end Check_Delayed_Subprogram;

   ------------------------------------
   -- Check_Discriminant_Conformance --
   ------------------------------------

   procedure Check_Discriminant_Conformance
     (N        : Node_Id;
      Prev     : Entity_Id;
      Prev_Loc : Node_Id)
   is
      Old_Discr      : Entity_Id := First_Discriminant (Prev);
      New_Discr      : Node_Id   := First (Discriminant_Specifications (N));
      New_Discr_Id   : Entity_Id;
      New_Discr_Type : Entity_Id;

      procedure Conformance_Error (Msg : String; N : Node_Id);
      --  Post error message for conformance error on given node. Two messages
      --  are output. The first points to the previous declaration with a
      --  general "no conformance" message. The second is the detailed reason,
      --  supplied as Msg. The parameter N provide information for a possible
      --  & insertion in the message.

      -----------------------
      -- Conformance_Error --
      -----------------------

      procedure Conformance_Error (Msg : String; N : Node_Id) is
      begin
         Error_Msg_Sloc := Sloc (Prev_Loc);
         Error_Msg_N -- CODEFIX
           ("not fully conformant with declaration#!", N);
         Error_Msg_NE (Msg, N, N);
      end Conformance_Error;

   --  Start of processing for Check_Discriminant_Conformance

   begin
      while Present (Old_Discr) and then Present (New_Discr) loop
         New_Discr_Id := Defining_Identifier (New_Discr);

         --  The subtype mark of the discriminant on the full type has not
         --  been analyzed so we do it here. For an access discriminant a new
         --  type is created.

         if Nkind (Discriminant_Type (New_Discr)) = N_Access_Definition then
            New_Discr_Type :=
              Access_Definition (N, Discriminant_Type (New_Discr));

         else
            Find_Type (Discriminant_Type (New_Discr));
            New_Discr_Type := Etype (Discriminant_Type (New_Discr));

            --  Ada 2005: if the discriminant definition carries a null
            --  exclusion, create an itype to check properly for consistency
            --  with partial declaration.

            if Is_Access_Type (New_Discr_Type)
              and then Null_Exclusion_Present (New_Discr)
            then
               New_Discr_Type :=
                 Create_Null_Excluding_Itype
                   (T           => New_Discr_Type,
                    Related_Nod => New_Discr,
                    Scope_Id    => Current_Scope);
            end if;
         end if;

         if not Conforming_Types
                  (Etype (Old_Discr), New_Discr_Type, Fully_Conformant)
         then
            Conformance_Error ("type of & does not match!", New_Discr_Id);
            return;
         else
            --  Treat the new discriminant as an occurrence of the old one,
            --  for navigation purposes, and fill in some semantic
            --  information, for completeness.

            Generate_Reference (Old_Discr, New_Discr_Id, 'r');
            Set_Etype (New_Discr_Id, Etype (Old_Discr));
            Set_Scope (New_Discr_Id, Scope (Old_Discr));
         end if;

         --  Names must match

         if Chars (Old_Discr) /= Chars (Defining_Identifier (New_Discr)) then
            Conformance_Error ("name & does not match!", New_Discr_Id);
            return;
         end if;

         --  Default expressions must match

         declare
            NewD : constant Boolean :=
                     Present (Expression (New_Discr));
            OldD : constant Boolean :=
                     Present (Expression (Parent (Old_Discr)));

         begin
            if NewD or OldD then

               --  The old default value has been analyzed and expanded,
               --  because the current full declaration will have frozen
               --  everything before. The new default values have not been
               --  expanded, so expand now to check conformance.

               if NewD then
                  Preanalyze_Spec_Expression
                    (Expression (New_Discr), New_Discr_Type);
               end if;

               if not (NewD and OldD)
                 or else not Fully_Conformant_Expressions
                              (Expression (Parent (Old_Discr)),
                               Expression (New_Discr))

               then
                  Conformance_Error
                    ("default expression for & does not match!",
                     New_Discr_Id);
                  return;
               end if;
            end if;
         end;

         --  In Ada 83 case, grouping must match: (A,B : X) /= (A : X; B : X)

         if Ada_Version = Ada_83 then
            declare
               Old_Disc : constant Node_Id := Declaration_Node (Old_Discr);

            begin
               --  Grouping (use of comma in param lists) must be the same
               --  This is where we catch a misconformance like:

               --    A, B : Integer
               --    A : Integer; B : Integer

               --  which are represented identically in the tree except
               --  for the setting of the flags More_Ids and Prev_Ids.

               if More_Ids (Old_Disc) /= More_Ids (New_Discr)
                 or else Prev_Ids (Old_Disc) /= Prev_Ids (New_Discr)
               then
                  Conformance_Error
                    ("grouping of & does not match!", New_Discr_Id);
                  return;
               end if;
            end;
         end if;

         Next_Discriminant (Old_Discr);
         Next (New_Discr);
      end loop;

      if Present (Old_Discr) then
         Conformance_Error ("too few discriminants!", Defining_Identifier (N));
         return;

      elsif Present (New_Discr) then
         Conformance_Error
           ("too many discriminants!", Defining_Identifier (New_Discr));
         return;
      end if;
   end Check_Discriminant_Conformance;

   -----------------------------------------
   -- Check_Formal_Subprogram_Conformance --
   -----------------------------------------

   procedure Check_Formal_Subprogram_Conformance
     (New_Id   : Entity_Id;
      Old_Id   : Entity_Id;
      Err_Loc  : Node_Id;
      Errmsg   : Boolean;
      Conforms : out Boolean)
   is
      N : Node_Id;
   begin
      Conforms := True;

      if Is_Formal_Subprogram (Old_Id)
        or else Is_Formal_Subprogram (New_Id)
        or else (Is_Subprogram (New_Id)
                  and then Present (Alias (New_Id))
                  and then Is_Formal_Subprogram (Alias (New_Id)))
      then
         if Present (Err_Loc) then
            N := Err_Loc;
         else
            N := New_Id;
         end if;

         Conforms := False;

         if Errmsg then
            Error_Msg_Sloc := Sloc (Old_Id);
            Error_Msg_N ("not subtype conformant with declaration#!", N);
            Error_Msg_NE
              ("\formal subprograms are not subtype conformant "
               & "(RM 6.3.1 (17/3))", N, New_Id);
         end if;
      end if;
   end Check_Formal_Subprogram_Conformance;

   procedure Check_Formal_Subprogram_Conformance
     (New_Id  : Entity_Id;
      Old_Id  : Entity_Id;
      Err_Loc : Node_Id := Empty)
   is
      Ignore : Boolean;
   begin
      Check_Formal_Subprogram_Conformance
        (New_Id, Old_Id, Err_Loc, True, Ignore);
   end Check_Formal_Subprogram_Conformance;

   ----------------------------
   -- Check_Fully_Conformant --
   ----------------------------

   procedure Check_Fully_Conformant
     (New_Id  : Entity_Id;
      Old_Id  : Entity_Id;
      Err_Loc : Node_Id := Empty)
   is
      Result : Boolean;
      pragma Warnings (Off, Result);
   begin
      Check_Conformance
        (New_Id, Old_Id, Fully_Conformant, True, Result, Err_Loc);
   end Check_Fully_Conformant;

   --------------------------
   -- Check_Limited_Return --
   --------------------------

   procedure Check_Limited_Return
     (N      : Node_Id;
      Expr   : Node_Id;
      R_Type : Entity_Id)
   is
   begin
      --  Ada 2005 (AI-318-02): Return-by-reference types have been removed and
      --  replaced by anonymous access results. This is an incompatibility with
      --  Ada 95. Not clear whether this should be enforced yet or perhaps
      --  controllable with special switch. ???

      --  A limited interface that is not immutably limited is OK

      if Is_Limited_Interface (R_Type)
        and then
          not (Is_Task_Interface (R_Type)
                or else Is_Protected_Interface (R_Type)
                or else Is_Synchronized_Interface (R_Type))
      then
         null;

      elsif Is_Limited_Type (R_Type)
        and then not Is_Interface (R_Type)
        and then Comes_From_Source (N)
        and then not In_Instance_Body
        and then not OK_For_Limited_Init_In_05 (R_Type, Expr)
      then
         --  Error in Ada 2005

         if Ada_Version >= Ada_2005
           and then not Debug_Flag_Dot_L
           and then not GNAT_Mode
         then
            Error_Msg_N
              ("(Ada 2005) cannot copy object of a limited type "
               & "(RM-2005 6.5(5.5/2))", Expr);

            if Is_Limited_View (R_Type) then
               Error_Msg_N
                 ("\return by reference not permitted in Ada 2005", Expr);
            end if;

         --  Warn in Ada 95 mode, to give folks a heads up about this
         --  incompatibility.

         --  In GNAT mode, this is just a warning, to allow it to be evilly
         --  turned off. Otherwise it is a real error.

         --  In a generic context, simplify the warning because it makes no
         --  sense to discuss pass-by-reference or copy.

         elsif Warn_On_Ada_2005_Compatibility or GNAT_Mode then
            if Inside_A_Generic then
               Error_Msg_N
                 ("return of limited object not permitted in Ada 2005 "
                  & "(RM-2005 6.5(5.5/2))?y?", Expr);

            elsif Is_Limited_View (R_Type) then
               Error_Msg_N
                 ("return by reference not permitted in Ada 2005 "
                  & "(RM-2005 6.5(5.5/2))?y?", Expr);
            else
               Error_Msg_N
                 ("cannot copy object of a limited type in Ada 2005 "
                  & "(RM-2005 6.5(5.5/2))?y?", Expr);
            end if;

         --  Ada 95 mode, and compatibility warnings disabled

         else
            pragma Assert (Ada_Version <= Ada_95);
            pragma Assert (not (Warn_On_Ada_2005_Compatibility or GNAT_Mode));
            return; --  skip continuation messages below
         end if;

         if not Inside_A_Generic then
            Error_Msg_N
              ("\consider switching to return of access type", Expr);
            Explain_Limited_Type (R_Type, Expr);
         end if;
      end if;
   end Check_Limited_Return;

   ---------------------------
   -- Check_Mode_Conformant --
   ---------------------------

   procedure Check_Mode_Conformant
     (New_Id   : Entity_Id;
      Old_Id   : Entity_Id;
      Err_Loc  : Node_Id := Empty;
      Get_Inst : Boolean := False)
   is
      Result : Boolean;
      pragma Warnings (Off, Result);
   begin
      Check_Conformance
        (New_Id, Old_Id, Mode_Conformant, True, Result, Err_Loc, Get_Inst);
   end Check_Mode_Conformant;

   --------------------------------
   -- Check_Overriding_Indicator --
   --------------------------------

   procedure Check_Overriding_Indicator
     (Subp            : Entity_Id;
      Overridden_Subp : Entity_Id;
      Is_Primitive    : Boolean)
   is
      Decl : Node_Id;
      Spec : Node_Id;

   begin
      --  No overriding indicator for literals

      if Ekind (Subp) = E_Enumeration_Literal then
         return;

      elsif Ekind (Subp) = E_Entry then
         Decl := Parent (Subp);

         --  No point in analyzing a malformed operator

      elsif Nkind (Subp) = N_Defining_Operator_Symbol
        and then Error_Posted (Subp)
      then
         return;

      else
         Decl := Unit_Declaration_Node (Subp);
      end if;

      if Nkind (Decl) in N_Subprogram_Body
                       | N_Subprogram_Body_Stub
                       | N_Subprogram_Declaration
                       | N_Abstract_Subprogram_Declaration
                       | N_Subprogram_Renaming_Declaration
      then
         Spec := Specification (Decl);

      elsif Nkind (Decl) = N_Entry_Declaration then
         Spec := Decl;

      else
         return;
      end if;

      --  An overriding indication is illegal on a subprogram declared
      --  in a protected body, where there is no operation to override.

      if (Must_Override (Spec) or else Must_Not_Override (Spec))
        and then Is_List_Member (Decl)
        and then Present (Parent (List_Containing (Decl)))
        and then Nkind (Parent (List_Containing (Decl))) = N_Protected_Body
      then
         Error_Msg_N
           ("illegal overriding indication in protected body", Decl);
         return;
      end if;

      --  The overriding operation is type conformant with the overridden one,
      --  but the names of the formals are not required to match. If the names
      --  appear permuted in the overriding operation, this is a possible
      --  source of confusion that is worth diagnosing. Controlling formals
      --  often carry names that reflect the type, and it is not worthwhile
      --  requiring that their names match.

      if Present (Overridden_Subp)
        and then Nkind (Subp) /= N_Defining_Operator_Symbol
      then
         declare
            Form1 : Entity_Id;
            Form2 : Entity_Id;

         begin
            Form1 := First_Formal (Subp);
            Form2 := First_Formal (Overridden_Subp);

            --  If the overriding operation is a synchronized operation, skip
            --  the first parameter of the overridden operation, which is
            --  implicit in the new one. If the operation is declared in the
            --  body it is not primitive and all formals must match.

            if Is_Concurrent_Type (Scope (Subp))
              and then Is_Tagged_Type (Scope (Subp))
              and then not Has_Completion (Scope (Subp))
            then
               Form2 := Next_Formal (Form2);
            end if;

            if Present (Form1) then
               Form1 := Next_Formal (Form1);
               Form2 := Next_Formal (Form2);
            end if;

            while Present (Form1) loop
               if not Is_Controlling_Formal (Form1)
                 and then Present (Next_Formal (Form2))
                 and then Chars (Form1) = Chars (Next_Formal (Form2))
               then
                  Error_Msg_Node_2 := Alias (Overridden_Subp);
                  Error_Msg_Sloc := Sloc (Error_Msg_Node_2);
                  Error_Msg_NE
                    ("& does not match corresponding formal of&#",
                     Form1, Form1);
                  exit;
               end if;

               Next_Formal (Form1);
               Next_Formal (Form2);
            end loop;
         end;
      end if;

      --  If there is an overridden subprogram, then check that there is no
      --  "not overriding" indicator, and mark the subprogram as overriding.

      --  This is not done if the overridden subprogram is marked as hidden,
      --  which can occur for the case of inherited controlled operations
      --  (see Derive_Subprogram), unless the inherited subprogram's parent
      --  subprogram is not itself hidden or we are within a generic instance,
      --  in which case the hidden flag may have been modified for the
      --  expansion of the instance.

      --  (Note: This condition could probably be simplified, leaving out the
      --  testing for the specific controlled cases, but it seems safer and
      --  clearer this way, and echoes similar special-case tests of this
      --  kind in other places.)

      if Present (Overridden_Subp)
        and then (not Is_Hidden (Overridden_Subp)
                   or else
                     (Chars (Overridden_Subp) in Name_Initialize
                                               | Name_Adjust
                                               | Name_Finalize
                      and then Present (Alias (Overridden_Subp))
                      and then (not Is_Hidden (Alias (Overridden_Subp))
                                 or else In_Instance)))
      then
         if Must_Not_Override (Spec) then
            Error_Msg_Sloc := Sloc (Overridden_Subp);

            if Ekind (Subp) = E_Entry then
               Error_Msg_NE
                 ("entry & overrides inherited operation #", Spec, Subp);
            else
               Error_Msg_NE
                 ("subprogram & overrides inherited operation #", Spec, Subp);
            end if;

         --  Special-case to fix a GNAT oddity: Limited_Controlled is declared
         --  as an extension of Root_Controlled, and thus has a useless Adjust
         --  operation. This operation should not be inherited by other limited
         --  controlled types. An explicit Adjust for them is not overriding.

         elsif Must_Override (Spec)
           and then Chars (Overridden_Subp) = Name_Adjust
           and then Is_Limited_Type (Etype (First_Formal (Subp)))
           and then Present (Alias (Overridden_Subp))
           and then In_Predefined_Unit (Alias (Overridden_Subp))
         then
            Get_Name_String
              (Unit_File_Name (Get_Source_Unit (Alias (Overridden_Subp))));
            Error_Msg_NE ("subprogram & is not overriding", Spec, Subp);

         elsif Is_Subprogram (Subp) then
            if Is_Init_Proc (Subp) then
               null;

            elsif No (Overridden_Operation (Subp)) then

               --  For entities generated by Derive_Subprograms the overridden
               --  operation is the inherited primitive (which is available
               --  through the attribute alias)

               if (Is_Dispatching_Operation (Subp)
                    or else Is_Dispatching_Operation (Overridden_Subp))
                 and then not Comes_From_Source (Overridden_Subp)
                 and then Find_Dispatching_Type (Overridden_Subp) =
                          Find_Dispatching_Type (Subp)
                 and then Present (Alias (Overridden_Subp))
                 and then Comes_From_Source (Alias (Overridden_Subp))
               then
                  Set_Overridden_Operation    (Subp, Alias (Overridden_Subp));
                  Inherit_Subprogram_Contract (Subp, Alias (Overridden_Subp));

               else
                  Set_Overridden_Operation    (Subp, Overridden_Subp);
                  Inherit_Subprogram_Contract (Subp, Overridden_Subp);
               end if;
            end if;
         end if;

         --  If primitive flag is set or this is a protected operation, then
         --  the operation is overriding at the point of its declaration, so
         --  warn if necessary. Otherwise it may have been declared before the
         --  operation it overrides and no check is required.

         if Style_Check
           and then not Must_Override (Spec)
           and then (Is_Primitive
                      or else Ekind (Scope (Subp)) = E_Protected_Type)
         then
            Style.Missing_Overriding (Decl, Subp);
         end if;

      --  If Subp is an operator, it may override a predefined operation, if
      --  it is defined in the same scope as the type to which it applies.
      --  In that case Overridden_Subp is empty because of our implicit
      --  representation for predefined operators. We have to check whether the
      --  signature of Subp matches that of a predefined operator. Note that
      --  first argument provides the name of the operator, and the second
      --  argument the signature that may match that of a standard operation.
      --  If the indicator is overriding, then the operator must match a
      --  predefined signature, because we know already that there is no
      --  explicit overridden operation.

      elsif Nkind (Subp) = N_Defining_Operator_Symbol then
         if Must_Not_Override (Spec) then

            --  If this is not a primitive or a protected subprogram, then
            --  "not overriding" is illegal.

            if not Is_Primitive
              and then Ekind (Scope (Subp)) /= E_Protected_Type
            then
               Error_Msg_N ("overriding indicator only allowed "
                            & "if subprogram is primitive", Subp);

            elsif Can_Override_Operator (Subp) then
               Error_Msg_NE
                 ("subprogram& overrides predefined operator", Spec, Subp);
            end if;

         elsif Must_Override (Spec) then
            if No (Overridden_Operation (Subp))
              and then not Can_Override_Operator (Subp)
            then
               Error_Msg_NE ("subprogram & is not overriding", Spec, Subp);
            end if;

         elsif not Error_Posted (Subp)
           and then Style_Check
           and then Can_Override_Operator (Subp)
           and then not In_Predefined_Unit (Subp)
         then
            --  If style checks are enabled, indicate that the indicator is
            --  missing. However, at the point of declaration, the type of
            --  which this is a primitive operation may be private, in which
            --  case the indicator would be premature.

            if Has_Private_Declaration (Etype (Subp))
              or else Has_Private_Declaration (Etype (First_Formal (Subp)))
            then
               null;
            else
               Style.Missing_Overriding (Decl, Subp);
            end if;
         end if;

      elsif Must_Override (Spec) then
         if Ekind (Subp) = E_Entry then
            Error_Msg_NE ("entry & is not overriding", Spec, Subp);
         else
            Error_Msg_NE ("subprogram & is not overriding", Spec, Subp);
         end if;

      --  If the operation is marked "not overriding" and it's not primitive
      --  then an error is issued, unless this is an operation of a task or
      --  protected type (RM05-8.3.1(3/2-4/2)). Error cases where "overriding"
      --  has been specified have already been checked above.

      elsif Must_Not_Override (Spec)
        and then not Is_Primitive
        and then Ekind (Subp) /= E_Entry
        and then Ekind (Scope (Subp)) /= E_Protected_Type
      then
         Error_Msg_N
           ("overriding indicator only allowed if subprogram is primitive",
            Subp);
         return;
      end if;
   end Check_Overriding_Indicator;

   -------------------
   -- Check_Returns --
   -------------------

   --  Note: this procedure needs to know far too much about how the expander
   --  messes with exceptions. The use of the flag Exception_Junk and the
   --  incorporation of knowledge of Exp_Ch11.Expand_Local_Exception_Handlers
   --  works, but is not very clean. It would be better if the expansion
   --  routines would leave Original_Node working nicely, and we could use
   --  Original_Node here to ignore all the peculiar expander messing ???

   procedure Check_Returns
     (HSS  : Node_Id;
      Mode : Character;
      Err  : out Boolean;
      Proc : Entity_Id := Empty)
   is
      Handler : Node_Id;

      procedure Check_Statement_Sequence (L : List_Id);
      --  Internal recursive procedure to check a list of statements for proper
      --  termination by a return statement (or a transfer of control or a
      --  compound statement that is itself internally properly terminated).

      ------------------------------
      -- Check_Statement_Sequence --
      ------------------------------

      procedure Check_Statement_Sequence (L : List_Id) is
         Last_Stm : Node_Id;
         Stm      : Node_Id;
         Kind     : Node_Kind;

         function Assert_False return Boolean;
         --  Returns True if Last_Stm is a pragma Assert (False) that has been
         --  rewritten as a null statement when assertions are off. The assert
         --  is not active, but it is still enough to kill the warning.

         ------------------
         -- Assert_False --
         ------------------

         function Assert_False return Boolean is
            Orig : constant Node_Id := Original_Node (Last_Stm);

         begin
            if Nkind (Orig) = N_Pragma
              and then Pragma_Name (Orig) = Name_Assert
              and then not Error_Posted (Orig)
            then
               declare
                  Arg : constant Node_Id :=
                          First (Pragma_Argument_Associations (Orig));
                  Exp : constant Node_Id := Expression (Arg);
               begin
                  return Nkind (Exp) = N_Identifier
                    and then Chars (Exp) = Name_False;
               end;

            else
               return False;
            end if;
         end Assert_False;

         --  Local variables

         Raise_Exception_Call : Boolean;
         --  Set True if statement sequence terminated by Raise_Exception call
         --  or a Reraise_Occurrence call.

      --  Start of processing for Check_Statement_Sequence

      begin
         Raise_Exception_Call := False;

         --  Get last real statement

         Last_Stm := Last (L);

         --  Deal with digging out exception handler statement sequences that
         --  have been transformed by the local raise to goto optimization.
         --  See Exp_Ch11.Expand_Local_Exception_Handlers for details. If this
         --  optimization has occurred, we are looking at something like:

         --  begin
         --     original stmts in block

         --  exception            \
         --     when excep1 =>     |
         --        goto L1;        | omitted if No_Exception_Propagation
         --     when excep2 =>     |
         --        goto L2;       /
         --  end;

         --  goto L3;      -- skip handler when exception not raised

         --  <<L1>>        -- target label for local exception
         --     begin
         --        estmts1
         --     end;

         --     goto L3;

         --  <<L2>>
         --     begin
         --        estmts2
         --     end;

         --  <<L3>>

         --  and what we have to do is to dig out the estmts1 and estmts2
         --  sequences (which were the original sequences of statements in
         --  the exception handlers) and check them.

         if Nkind (Last_Stm) = N_Label and then Exception_Junk (Last_Stm) then
            Stm := Last_Stm;
            loop
               Prev (Stm);
               exit when No (Stm);
               exit when Nkind (Stm) /= N_Block_Statement;
               exit when not Exception_Junk (Stm);
               Prev (Stm);
               exit when No (Stm);
               exit when Nkind (Stm) /= N_Label;
               exit when not Exception_Junk (Stm);
               Check_Statement_Sequence
                 (Statements (Handled_Statement_Sequence (Next (Stm))));

               Prev (Stm);
               Last_Stm := Stm;
               exit when No (Stm);
               exit when Nkind (Stm) /= N_Goto_Statement;
               exit when not Exception_Junk (Stm);
            end loop;
         end if;

         --  Don't count pragmas

         while Nkind (Last_Stm) = N_Pragma

         --  Don't count call to SS_Release (can happen after Raise_Exception)

           or else
             (Nkind (Last_Stm) = N_Procedure_Call_Statement
                and then
              Nkind (Name (Last_Stm)) = N_Identifier
                and then
              Is_RTE (Entity (Name (Last_Stm)), RE_SS_Release))

         --  Don't count exception junk

           or else
             (Nkind (Last_Stm) in
                N_Goto_Statement | N_Label | N_Object_Declaration
               and then Exception_Junk (Last_Stm))
           or else Nkind (Last_Stm) in N_Push_xxx_Label | N_Pop_xxx_Label

         --  Inserted code, such as finalization calls, is irrelevant: we only
         --  need to check original source.

           or else Is_Rewrite_Insertion (Last_Stm)
         loop
            Prev (Last_Stm);
         end loop;

         --  Here we have the "real" last statement

         Kind := Nkind (Last_Stm);

         --  Transfer of control, OK. Note that in the No_Return procedure
         --  case, we already diagnosed any explicit return statements, so
         --  we can treat them as OK in this context.

         if Is_Transfer (Last_Stm) then
            return;

         --  Check cases of explicit non-indirect procedure calls

         elsif Kind = N_Procedure_Call_Statement
           and then Is_Entity_Name (Name (Last_Stm))
         then
            --  Check call to Raise_Exception procedure which is treated
            --  specially, as is a call to Reraise_Occurrence.

            --  We suppress the warning in these cases since it is likely that
            --  the programmer really does not expect to deal with the case
            --  of Null_Occurrence, and thus would find a warning about a
            --  missing return curious, and raising Program_Error does not
            --  seem such a bad behavior if this does occur.

            --  Note that in the Ada 2005 case for Raise_Exception, the actual
            --  behavior will be to raise Constraint_Error (see AI-329).

            if Is_RTE (Entity (Name (Last_Stm)), RE_Raise_Exception)
                 or else
               Is_RTE (Entity (Name (Last_Stm)), RE_Reraise_Occurrence)
            then
               Raise_Exception_Call := True;

               --  For Raise_Exception call, test first argument, if it is
               --  an attribute reference for a 'Identity call, then we know
               --  that the call cannot possibly return.

               declare
                  Arg : constant Node_Id :=
                          Original_Node (First_Actual (Last_Stm));
               begin
                  if Nkind (Arg) = N_Attribute_Reference
                    and then Attribute_Name (Arg) = Name_Identity
                  then
                     return;
                  end if;
               end;
            end if;

         --  If statement, need to look inside if there is an else and check
         --  each constituent statement sequence for proper termination.

         elsif Kind = N_If_Statement
           and then Present (Else_Statements (Last_Stm))
         then
            Check_Statement_Sequence (Then_Statements (Last_Stm));
            Check_Statement_Sequence (Else_Statements (Last_Stm));

            if Present (Elsif_Parts (Last_Stm)) then
               declare
                  Elsif_Part : Node_Id := First (Elsif_Parts (Last_Stm));

               begin
                  while Present (Elsif_Part) loop
                     Check_Statement_Sequence (Then_Statements (Elsif_Part));
                     Next (Elsif_Part);
                  end loop;
               end;
            end if;

            return;

         --  Case statement, check each case for proper termination

         elsif Kind = N_Case_Statement then
            declare
               Case_Alt : Node_Id;
            begin
               Case_Alt := First_Non_Pragma (Alternatives (Last_Stm));
               while Present (Case_Alt) loop
                  Check_Statement_Sequence (Statements (Case_Alt));
                  Next_Non_Pragma (Case_Alt);
               end loop;
            end;

            return;

         --  Block statement, check its handled sequence of statements

         elsif Kind = N_Block_Statement then
            declare
               Err1 : Boolean;

            begin
               Check_Returns
                 (Handled_Statement_Sequence (Last_Stm), Mode, Err1);

               if Err1 then
                  Err := True;
               end if;

               return;
            end;

         --  Loop statement. If there is an iteration scheme, we can definitely
         --  fall out of the loop. Similarly if there is an exit statement, we
         --  can fall out. In either case we need a following return.

         elsif Kind = N_Loop_Statement then
            if Present (Iteration_Scheme (Last_Stm))
              or else Has_Exit (Entity (Identifier (Last_Stm)))
            then
               null;

            --  A loop with no exit statement or iteration scheme is either
            --  an infinite loop, or it has some other exit (raise/return).
            --  In either case, no warning is required.

            else
               return;
            end if;

         --  Timed entry call, check entry call and delay alternatives

         --  Note: in expanded code, the timed entry call has been converted
         --  to a set of expanded statements on which the check will work
         --  correctly in any case.

         elsif Kind = N_Timed_Entry_Call then
            declare
               ECA : constant Node_Id := Entry_Call_Alternative (Last_Stm);
               DCA : constant Node_Id := Delay_Alternative      (Last_Stm);

            begin
               --  If statement sequence of entry call alternative is missing,
               --  then we can definitely fall through, and we post the error
               --  message on the entry call alternative itself.

               if No (Statements (ECA)) then
                  Last_Stm := ECA;

               --  If statement sequence of delay alternative is missing, then
               --  we can definitely fall through, and we post the error
               --  message on the delay alternative itself.

               --  Note: if both ECA and DCA are missing the return, then we
               --  post only one message, should be enough to fix the bugs.
               --  If not we will get a message next time on the DCA when the
               --  ECA is fixed.

               elsif No (Statements (DCA)) then
                  Last_Stm := DCA;

               --  Else check both statement sequences

               else
                  Check_Statement_Sequence (Statements (ECA));
                  Check_Statement_Sequence (Statements (DCA));
                  return;
               end if;
            end;

         --  Conditional entry call, check entry call and else part

         --  Note: in expanded code, the conditional entry call has been
         --  converted to a set of expanded statements on which the check
         --  will work correctly in any case.

         elsif Kind = N_Conditional_Entry_Call then
            declare
               ECA : constant Node_Id := Entry_Call_Alternative (Last_Stm);

            begin
               --  If statement sequence of entry call alternative is missing,
               --  then we can definitely fall through, and we post the error
               --  message on the entry call alternative itself.

               if No (Statements (ECA)) then
                  Last_Stm := ECA;

               --  Else check statement sequence and else part

               else
                  Check_Statement_Sequence (Statements (ECA));
                  Check_Statement_Sequence (Else_Statements (Last_Stm));
                  return;
               end if;
            end;
         end if;

         --  If we fall through, issue appropriate message

         if Mode = 'F' then

            --  Kill warning if last statement is a raise exception call,
            --  or a pragma Assert (False). Note that with assertions enabled,
            --  such a pragma has been converted into a raise exception call
            --  already, so the Assert_False is for the assertions off case.

            if not Raise_Exception_Call and then not Assert_False then

               --  In GNATprove mode, it is an error to have a missing return

               Error_Msg_Warn := SPARK_Mode /= On;

               --  Issue error message or warning

               Error_Msg_N
                 ("RETURN statement missing following this statement<<!",
                  Last_Stm);
               Error_Msg_N
                 ("\Program_Error ]<<!", Last_Stm);
            end if;

            --  Note: we set Err even though we have not issued a warning
            --  because we still have a case of a missing return. This is
            --  an extremely marginal case, probably will never be noticed
            --  but we might as well get it right.

            Err := True;

         --  Otherwise we have the case of a procedure marked No_Return

         else
            if not Raise_Exception_Call then
               if GNATprove_Mode then
                  Error_Msg_N
                    ("implied return after this statement would have raised "
                     & "Program_Error", Last_Stm);

               --  In normal compilation mode, do not warn on a generated call
               --  (e.g. in the body of a renaming as completion).

               elsif Comes_From_Source (Last_Stm) then
                  Error_Msg_N
                    ("implied return after this statement will raise "
                     & "Program_Error??", Last_Stm);
               end if;

               Error_Msg_Warn := SPARK_Mode /= On;
               Error_Msg_NE
                 ("\procedure & is marked as No_Return<<!", Last_Stm, Proc);
            end if;

            declare
               RE : constant Node_Id :=
                      Make_Raise_Program_Error (Sloc (Last_Stm),
                        Reason => PE_Implicit_Return);
            begin
               Insert_After (Last_Stm, RE);
               Analyze (RE);
            end;
         end if;
      end Check_Statement_Sequence;

   --  Start of processing for Check_Returns

   begin
      Err := False;
      Check_Statement_Sequence (Statements (HSS));

      if Present (Exception_Handlers (HSS)) then
         Handler := First_Non_Pragma (Exception_Handlers (HSS));
         while Present (Handler) loop
            Check_Statement_Sequence (Statements (Handler));
            Next_Non_Pragma (Handler);
         end loop;
      end if;
   end Check_Returns;

   ----------------------------
   -- Check_Subprogram_Order --
   ----------------------------

   procedure Check_Subprogram_Order (N : Node_Id) is

      function Subprogram_Name_Greater (S1, S2 : String) return Boolean;
      --  This is used to check if S1 > S2 in the sense required by this test,
      --  for example nameab < namec, but name2 < name10.

      -----------------------------
      -- Subprogram_Name_Greater --
      -----------------------------

      function Subprogram_Name_Greater (S1, S2 : String) return Boolean is
         L1, L2 : Positive;
         N1, N2 : Natural;

      begin
         --  Deal with special case where names are identical except for a
         --  numerical suffix. These are handled specially, taking the numeric
         --  ordering from the suffix into account.

         L1 := S1'Last;
         while S1 (L1) in '0' .. '9' loop
            L1 := L1 - 1;
         end loop;

         L2 := S2'Last;
         while S2 (L2) in '0' .. '9' loop
            L2 := L2 - 1;
         end loop;

         --  If non-numeric parts non-equal, do straight compare

         if S1 (S1'First .. L1) /= S2 (S2'First .. L2) then
            return S1 > S2;

         --  If non-numeric parts equal, compare suffixed numeric parts. Note
         --  that a missing suffix is treated as numeric zero in this test.

         else
            N1 := 0;
            while L1 < S1'Last loop
               L1 := L1 + 1;
               N1 := N1 * 10 + Character'Pos (S1 (L1)) - Character'Pos ('0');
            end loop;

            N2 := 0;
            while L2 < S2'Last loop
               L2 := L2 + 1;
               N2 := N2 * 10 + Character'Pos (S2 (L2)) - Character'Pos ('0');
            end loop;

            return N1 > N2;
         end if;
      end Subprogram_Name_Greater;

   --  Start of processing for Check_Subprogram_Order

   begin
      --  Check body in alpha order if this is option

      if Style_Check
        and then Style_Check_Order_Subprograms
        and then Nkind (N) = N_Subprogram_Body
        and then Comes_From_Source (N)
        and then In_Extended_Main_Source_Unit (N)
      then
         declare
            LSN : String_Ptr
                    renames Scope_Stack.Table
                              (Scope_Stack.Last).Last_Subprogram_Name;

            Body_Id : constant Entity_Id :=
                        Defining_Entity (Specification (N));

         begin
            Get_Decoded_Name_String (Chars (Body_Id));

            if LSN /= null then
               if Subprogram_Name_Greater
                    (LSN.all, Name_Buffer (1 .. Name_Len))
               then
                  Style.Subprogram_Not_In_Alpha_Order (Body_Id);
               end if;

               Free (LSN);
            end if;

            LSN := new String'(Name_Buffer (1 .. Name_Len));
         end;
      end if;
   end Check_Subprogram_Order;

   ------------------------------
   -- Check_Subtype_Conformant --
   ------------------------------

   procedure Check_Subtype_Conformant
     (New_Id                   : Entity_Id;
      Old_Id                   : Entity_Id;
      Err_Loc                  : Node_Id := Empty;
      Skip_Controlling_Formals : Boolean := False;
      Get_Inst                 : Boolean := False)
   is
      Result : Boolean;
      pragma Warnings (Off, Result);
   begin
      Check_Conformance
        (New_Id, Old_Id, Subtype_Conformant, True, Result, Err_Loc,
         Skip_Controlling_Formals => Skip_Controlling_Formals,
         Get_Inst                 => Get_Inst);
   end Check_Subtype_Conformant;

   -----------------------------------
   -- Check_Synchronized_Overriding --
   -----------------------------------

   procedure Check_Synchronized_Overriding
     (Def_Id          : Entity_Id;
      Overridden_Subp : out Entity_Id)
   is
      Ifaces_List : Elist_Id;
      In_Scope    : Boolean;
      Typ         : Entity_Id;

      function Is_Valid_Formal (F : Entity_Id) return Boolean;
      --  Predicate for legality rule in 9.4 (11.9/2): If an inherited
      --  subprogram is implemented by a protected procedure or entry,
      --  its first parameter must be out, in out, or access-to-variable.

      function Matches_Prefixed_View_Profile
        (Prim_Params  : List_Id;
         Iface_Params : List_Id) return Boolean;
      --  Determine whether a subprogram's parameter profile Prim_Params
      --  matches that of a potentially overridden interface subprogram
      --  Iface_Params. Also determine if the type of first parameter of
      --  Iface_Params is an implemented interface.

      ----------------------
      --  Is_Valid_Formal --
      ----------------------

      function Is_Valid_Formal (F : Entity_Id) return Boolean is
      begin
         return
           Ekind (F) in E_In_Out_Parameter | E_Out_Parameter
             or else
               (Nkind (Parameter_Type (Parent (F))) = N_Access_Definition
                 and then not Constant_Present (Parameter_Type (Parent (F))));
      end Is_Valid_Formal;

      -----------------------------------
      -- Matches_Prefixed_View_Profile --
      -----------------------------------

      function Matches_Prefixed_View_Profile
        (Prim_Params  : List_Id;
         Iface_Params : List_Id) return Boolean
      is
         function Is_Implemented
           (Ifaces_List : Elist_Id;
            Iface       : Entity_Id) return Boolean;
         --  Determine if Iface is implemented by the current task or
         --  protected type.

         --------------------
         -- Is_Implemented --
         --------------------

         function Is_Implemented
           (Ifaces_List : Elist_Id;
            Iface       : Entity_Id) return Boolean
         is
            Iface_Elmt : Elmt_Id;

         begin
            Iface_Elmt := First_Elmt (Ifaces_List);
            while Present (Iface_Elmt) loop
               if Node (Iface_Elmt) = Iface then
                  return True;
               end if;

               Next_Elmt (Iface_Elmt);
            end loop;

            return False;
         end Is_Implemented;

         --  Local variables

         Iface_Id     : Entity_Id;
         Iface_Param  : Node_Id;
         Iface_Typ    : Entity_Id;
         Prim_Id      : Entity_Id;
         Prim_Param   : Node_Id;
         Prim_Typ     : Entity_Id;

      --  Start of processing for Matches_Prefixed_View_Profile

      begin
         Iface_Param := First (Iface_Params);
         Iface_Typ   := Etype (Defining_Identifier (Iface_Param));

         if Is_Access_Type (Iface_Typ) then
            Iface_Typ := Designated_Type (Iface_Typ);
         end if;

         Prim_Param := First (Prim_Params);

         --  The first parameter of the potentially overridden subprogram must
         --  be an interface implemented by Prim.

         if not Is_Interface (Iface_Typ)
           or else not Is_Implemented (Ifaces_List, Iface_Typ)
         then
            return False;
         end if;

         --  The checks on the object parameters are done, so move on to the
         --  rest of the parameters.

         if not In_Scope then
            Next (Prim_Param);
         end if;

         Next (Iface_Param);
         while Present (Iface_Param) and then Present (Prim_Param) loop
            Iface_Id  := Defining_Identifier (Iface_Param);
            Iface_Typ := Find_Parameter_Type (Iface_Param);

            Prim_Id  := Defining_Identifier (Prim_Param);
            Prim_Typ := Find_Parameter_Type (Prim_Param);

            if Ekind (Iface_Typ) = E_Anonymous_Access_Type
              and then Ekind (Prim_Typ) = E_Anonymous_Access_Type
              and then Is_Concurrent_Type (Designated_Type (Prim_Typ))
            then
               Iface_Typ := Designated_Type (Iface_Typ);
               Prim_Typ  := Designated_Type (Prim_Typ);
            end if;

            --  Case of multiple interface types inside a parameter profile

            --     (Obj_Param : in out Iface; ...; Param : Iface)

            --  If the interface type is implemented, then the matching type in
            --  the primitive should be the implementing record type.

            if Ekind (Iface_Typ) = E_Record_Type
              and then Is_Interface (Iface_Typ)
              and then Is_Implemented (Ifaces_List, Iface_Typ)
            then
               if Prim_Typ /= Typ then
                  return False;
               end if;

            --  The two parameters must be both mode and subtype conformant

            elsif Ekind (Iface_Id) /= Ekind (Prim_Id)
              or else not
                Conforming_Types (Iface_Typ, Prim_Typ, Subtype_Conformant)
            then
               return False;
            end if;

            Next (Iface_Param);
            Next (Prim_Param);
         end loop;

         --  One of the two lists contains more parameters than the other

         if Present (Iface_Param) or else Present (Prim_Param) then
            return False;
         end if;

         return True;
      end Matches_Prefixed_View_Profile;

   --  Start of processing for Check_Synchronized_Overriding

   begin
      Overridden_Subp := Empty;

      --  Def_Id must be an entry or a subprogram. We should skip predefined
      --  primitives internally generated by the front end; however at this
      --  stage predefined primitives are still not fully decorated. As a
      --  minor optimization we skip here internally generated subprograms.

      if (Ekind (Def_Id) /= E_Entry
           and then Ekind (Def_Id) /= E_Function
           and then Ekind (Def_Id) /= E_Procedure)
        or else not Comes_From_Source (Def_Id)
      then
         return;
      end if;

      --  Search for the concurrent declaration since it contains the list of
      --  all implemented interfaces. In this case, the subprogram is declared
      --  within the scope of a protected or a task type.

      if Present (Scope (Def_Id))
        and then Is_Concurrent_Type (Scope (Def_Id))
        and then not Is_Generic_Actual_Type (Scope (Def_Id))
      then
         Typ := Scope (Def_Id);
         In_Scope := True;

      --  The enclosing scope is not a synchronized type and the subprogram
      --  has no formals.

      elsif No (First_Formal (Def_Id)) then
         return;

      --  The subprogram has formals and hence it may be a primitive of a
      --  concurrent type.

      else
         Typ := Etype (First_Formal (Def_Id));

         if Is_Access_Type (Typ) then
            Typ := Directly_Designated_Type (Typ);
         end if;

         if Is_Concurrent_Type (Typ)
           and then not Is_Generic_Actual_Type (Typ)
         then
            In_Scope := False;

         --  This case occurs when the concurrent type is declared within a
         --  generic unit. As a result the corresponding record has been built
         --  and used as the type of the first formal, we just have to retrieve
         --  the corresponding concurrent type.

         elsif Is_Concurrent_Record_Type (Typ)
           and then not Is_Class_Wide_Type (Typ)
           and then Present (Corresponding_Concurrent_Type (Typ))
         then
            Typ := Corresponding_Concurrent_Type (Typ);
            In_Scope := False;

         else
            return;
         end if;
      end if;

      --  There is no overriding to check if this is an inherited operation in
      --  a type derivation for a generic actual.

      Collect_Interfaces (Typ, Ifaces_List);

      if Is_Empty_Elmt_List (Ifaces_List) then
         return;
      end if;

      --  Determine whether entry or subprogram Def_Id overrides a primitive
      --  operation that belongs to one of the interfaces in Ifaces_List.

      declare
         Candidate : Entity_Id := Empty;
         Hom       : Entity_Id := Empty;
         Subp      : Entity_Id := Empty;

      begin
         --  Traverse the homonym chain, looking for a potentially overridden
         --  subprogram that belongs to an implemented interface.

         Hom := Current_Entity_In_Scope (Def_Id);
         while Present (Hom) loop
            Subp := Hom;

            if Subp = Def_Id
              or else not Is_Overloadable (Subp)
              or else not Is_Primitive (Subp)
              or else not Is_Dispatching_Operation (Subp)
              or else not Present (Find_Dispatching_Type (Subp))
              or else not Is_Interface (Find_Dispatching_Type (Subp))
            then
               null;

            --  Entries and procedures can override abstract or null interface
            --  procedures.

            elsif Ekind (Def_Id) in E_Entry | E_Procedure
              and then Ekind (Subp) = E_Procedure
              and then Matches_Prefixed_View_Profile
                         (Parameter_Specifications (Parent (Def_Id)),
                          Parameter_Specifications (Parent (Subp)))
            then
               Candidate := Subp;

               --  For an overridden subprogram Subp, check whether the mode
               --  of its first parameter is correct depending on the kind of
               --  synchronized type.

               declare
                  Formal : constant Node_Id := First_Formal (Candidate);

               begin
                  --  In order for an entry or a protected procedure to
                  --  override, the first parameter of the overridden routine
                  --  must be of mode "out", "in out", or access-to-variable.

                  if Ekind (Candidate) in E_Entry | E_Procedure
                    and then Is_Protected_Type (Typ)
                    and then not Is_Valid_Formal (Formal)
                  then
                     null;

                  --  All other cases are OK since a task entry or routine does
                  --  not have a restriction on the mode of the first parameter
                  --  of the overridden interface routine.

                  else
                     Overridden_Subp := Candidate;
                     return;
                  end if;
               end;

            --  Functions can override abstract interface functions. Return
            --  types must be subtype conformant.

            elsif Ekind (Def_Id) = E_Function
              and then Ekind (Subp) = E_Function
              and then Matches_Prefixed_View_Profile
                         (Parameter_Specifications (Parent (Def_Id)),
                          Parameter_Specifications (Parent (Subp)))
              and then Conforming_Types
                         (Etype (Def_Id), Etype (Subp), Subtype_Conformant)
            then
               Candidate := Subp;

               --  If an inherited subprogram is implemented by a protected
               --  function, then the first parameter of the inherited
               --  subprogram shall be of mode in, but not an access-to-
               --  variable parameter (RM 9.4(11/9)).

               if Present (First_Formal (Subp))
                 and then Ekind (First_Formal (Subp)) = E_In_Parameter
                 and then
                   (not Is_Access_Type (Etype (First_Formal (Subp)))
                      or else
                    Is_Access_Constant (Etype (First_Formal (Subp))))
               then
                  Overridden_Subp := Subp;
                  return;
               end if;
            end if;

            Hom := Homonym (Hom);
         end loop;

         --  After examining all candidates for overriding, we are left with
         --  the best match, which is a mode-incompatible interface routine.

         if In_Scope and then Present (Candidate) then
            Error_Msg_PT (Def_Id, Candidate);
         end if;

         Overridden_Subp := Candidate;
         return;
      end;
   end Check_Synchronized_Overriding;

   ---------------------------
   -- Check_Type_Conformant --
   ---------------------------

   procedure Check_Type_Conformant
     (New_Id  : Entity_Id;
      Old_Id  : Entity_Id;
      Err_Loc : Node_Id := Empty)
   is
      Result : Boolean;
      pragma Warnings (Off, Result);
   begin
      Check_Conformance
        (New_Id, Old_Id, Type_Conformant, True, Result, Err_Loc);
   end Check_Type_Conformant;

   ---------------------------
   -- Can_Override_Operator --
   ---------------------------

   function Can_Override_Operator (Subp : Entity_Id) return Boolean is
      Typ : Entity_Id;

   begin
      if Nkind (Subp) /= N_Defining_Operator_Symbol then
         return False;

      else
         Typ := Base_Type (Etype (First_Formal (Subp)));

         --  Check explicitly that the operation is a primitive of the type

         return Operator_Matches_Spec (Subp, Subp)
           and then not Is_Generic_Type (Typ)
           and then Scope (Subp) = Scope (Typ)
           and then not Is_Class_Wide_Type (Typ);
      end if;
   end Can_Override_Operator;

   ----------------------
   -- Conforming_Types --
   ----------------------

   function Conforming_Types
     (T1       : Entity_Id;
      T2       : Entity_Id;
      Ctype    : Conformance_Type;
      Get_Inst : Boolean := False) return Boolean
   is
      function Base_Types_Match
        (Typ_1 : Entity_Id;
         Typ_2 : Entity_Id) return Boolean;
      --  If neither Typ_1 nor Typ_2 are generic actual types, or if they are
      --  in different scopes (e.g. parent and child instances), then verify
      --  that the base types are equal. Otherwise Typ_1 and Typ_2 must be on
      --  the same subtype chain. The whole purpose of this procedure is to
      --  prevent spurious ambiguities in an instantiation that may arise if
      --  two distinct generic types are instantiated with the same actual.

      function Find_Designated_Type (Typ : Entity_Id) return Entity_Id;
      --  An access parameter can designate an incomplete type. If the
      --  incomplete type is the limited view of a type from a limited_
      --  with_clause, check whether the non-limited view is available.
      --  If it is a (non-limited) incomplete type, get the full view.

      function Matches_Limited_With_View
        (Typ_1 : Entity_Id;
         Typ_2 : Entity_Id) return Boolean;
      --  Returns True if and only if either Typ_1 denotes a limited view of
      --  Typ_2 or Typ_2 denotes a limited view of Typ_1. This can arise when
      --  the limited with view of a type is used in a subprogram declaration
      --  and the subprogram body is in the scope of a regular with clause for
      --  the same unit. In such a case, the two type entities are considered
      --  identical for purposes of conformance checking.

      ----------------------
      -- Base_Types_Match --
      ----------------------

      function Base_Types_Match
        (Typ_1 : Entity_Id;
         Typ_2 : Entity_Id) return Boolean
      is
         Base_1 : constant Entity_Id := Base_Type (Typ_1);
         Base_2 : constant Entity_Id := Base_Type (Typ_2);

      begin
         if Typ_1 = Typ_2 then
            return True;

         elsif Base_1 = Base_2 then

            --  The following is too permissive. A more precise test should
            --  check that the generic actual is an ancestor subtype of the
            --  other ???.

            --  See code in Find_Corresponding_Spec that applies an additional
            --  filter to handle accidental amiguities in instances.

            return
              not Is_Generic_Actual_Type (Typ_1)
                or else not Is_Generic_Actual_Type (Typ_2)
                or else Scope (Typ_1) /= Scope (Typ_2);

         --  If Typ_2 is a generic actual type it is declared as the subtype of
         --  the actual. If that actual is itself a subtype we need to use its
         --  own base type to check for compatibility.

         elsif Ekind (Base_2) = Ekind (Typ_2)
           and then Base_1 = Base_Type (Base_2)
         then
            return True;

         elsif Ekind (Base_1) = Ekind (Typ_1)
           and then Base_2 = Base_Type (Base_1)
         then
            return True;

         else
            return False;
         end if;
      end Base_Types_Match;

      --------------------------
      -- Find_Designated_Type --
      --------------------------

      function Find_Designated_Type (Typ : Entity_Id) return Entity_Id is
         Desig : Entity_Id;

      begin
         Desig := Directly_Designated_Type (Typ);

         if Ekind (Desig) = E_Incomplete_Type then

            --  If regular incomplete type, get full view if available

            if Present (Full_View (Desig)) then
               Desig := Full_View (Desig);

            --  If limited view of a type, get non-limited view if available,
            --  and check again for a regular incomplete type.

            elsif Present (Non_Limited_View (Desig)) then
               Desig := Get_Full_View (Non_Limited_View (Desig));
            end if;
         end if;

         return Desig;
      end Find_Designated_Type;

      -------------------------------
      -- Matches_Limited_With_View --
      -------------------------------

      function Matches_Limited_With_View
        (Typ_1 : Entity_Id;
         Typ_2 : Entity_Id) return Boolean
      is
         function Is_Matching_Limited_View
           (Typ  : Entity_Id;
            View : Entity_Id) return Boolean;
         --  Determine whether non-limited view View denotes type Typ in some
         --  conformant fashion.

         ------------------------------
         -- Is_Matching_Limited_View --
         ------------------------------

         function Is_Matching_Limited_View
           (Typ  : Entity_Id;
            View : Entity_Id) return Boolean
         is
            Root_Typ  : Entity_Id;
            Root_View : Entity_Id;

         begin
            --  The non-limited view directly denotes the type

            if Typ = View then
               return True;

            --  The type is a subtype of the non-limited view

            elsif Is_Subtype_Of (Typ, View) then
               return True;

            --  Both the non-limited view and the type denote class-wide types

            elsif Is_Class_Wide_Type (Typ)
              and then Is_Class_Wide_Type (View)
            then
               Root_Typ  := Root_Type (Typ);
               Root_View := Root_Type (View);

               if Root_Typ = Root_View then
                  return True;

               --  An incomplete tagged type and its full view may receive two
               --  distinct class-wide types when the related package has not
               --  been analyzed yet.

               --    package Pack is
               --       type T is tagged;              --  CW_1
               --       type T is tagged null record;  --  CW_2
               --    end Pack;

               --  This is because the package lacks any semantic information
               --  that may eventually link both views of T. As a consequence,
               --  a client of the limited view of Pack will see CW_2 while a
               --  client of the non-limited view of Pack will see CW_1.

               elsif Is_Incomplete_Type (Root_Typ)
                 and then Present (Full_View (Root_Typ))
                 and then Full_View (Root_Typ) = Root_View
               then
                  return True;

               elsif Is_Incomplete_Type (Root_View)
                 and then Present (Full_View (Root_View))
                 and then Full_View (Root_View) = Root_Typ
               then
                  return True;
               end if;
            end if;

            return False;
         end Is_Matching_Limited_View;

      --  Start of processing for Matches_Limited_With_View

      begin
         --  In some cases a type imported through a limited_with clause, and
         --  its non-limited view are both visible, for example in an anonymous
         --  access-to-class-wide type in a formal, or when building the body
         --  for a subprogram renaming after the subprogram has been frozen.
         --  In these cases both entities designate the same type. In addition,
         --  if one of them is an actual in an instance, it may be a subtype of
         --  the non-limited view of the other.

         if From_Limited_With (Typ_1)
           and then From_Limited_With (Typ_2)
           and then Available_View (Typ_1) = Available_View (Typ_2)
         then
            return True;

         elsif From_Limited_With (Typ_1) then
            return Is_Matching_Limited_View (Typ_2, Available_View (Typ_1));

         elsif From_Limited_With (Typ_2) then
            return Is_Matching_Limited_View (Typ_1, Available_View (Typ_2));

         else
            return False;
         end if;
      end Matches_Limited_With_View;

      --  Local variables

      Are_Anonymous_Access_To_Subprogram_Types : Boolean := False;

      Type_1 : Entity_Id := T1;
      Type_2 : Entity_Id := T2;

   --  Start of processing for Conforming_Types

   begin
      --  The context is an instance association for a formal access-to-
      --  subprogram type; the formal parameter types require mapping because
      --  they may denote other formal parameters of the generic unit.

      if Get_Inst then
         Type_1 := Get_Instance_Of (T1);
         Type_2 := Get_Instance_Of (T2);
      end if;

      --  If one of the types is a view of the other introduced by a limited
      --  with clause, treat these as conforming for all purposes.

      if Matches_Limited_With_View (T1, T2) then
         return True;

      elsif Base_Types_Match (Type_1, Type_2) then
         if Ctype <= Mode_Conformant then
            return True;

         else
            return
              Subtypes_Statically_Match (Type_1, Type_2)
                and then Dimensions_Match (Type_1, Type_2);
         end if;

      elsif Is_Incomplete_Or_Private_Type (Type_1)
        and then Present (Full_View (Type_1))
        and then Base_Types_Match (Full_View (Type_1), Type_2)
      then
         return
           Ctype <= Mode_Conformant
             or else Subtypes_Statically_Match (Full_View (Type_1), Type_2);

      elsif Ekind (Type_2) = E_Incomplete_Type
        and then Present (Full_View (Type_2))
        and then Base_Types_Match (Type_1, Full_View (Type_2))
      then
         return
           Ctype <= Mode_Conformant
             or else Subtypes_Statically_Match (Type_1, Full_View (Type_2));

      elsif Is_Private_Type (Type_2)
        and then In_Instance
        and then Present (Full_View (Type_2))
        and then Base_Types_Match (Type_1, Full_View (Type_2))
      then
         return
           Ctype <= Mode_Conformant
             or else Subtypes_Statically_Match (Type_1, Full_View (Type_2));

      --  Another confusion between views in a nested instance with an
      --  actual private type whose full view is not in scope.

      elsif Ekind (Type_2) = E_Private_Subtype
        and then In_Instance
        and then Etype (Type_2) = Type_1
      then
         return True;

      --  In Ada 2012, incomplete types (including limited views) can appear
      --  as actuals in instantiations, where they are conformant to the
      --  corresponding incomplete formal.

      elsif Is_Incomplete_Type (Type_1)
        and then Is_Incomplete_Type (Type_2)
        and then In_Instance
        and then (Used_As_Generic_Actual (Type_1)
                   or else Used_As_Generic_Actual (Type_2))
      then
         return True;
      end if;

      --  Ada 2005 (AI-254): Anonymous access-to-subprogram types must be
      --  treated recursively because they carry a signature. As far as
      --  conformance is concerned, convention plays no role, and either
      --  or both could be access to protected subprograms.

      Are_Anonymous_Access_To_Subprogram_Types :=
        Ekind (Type_1) in E_Anonymous_Access_Subprogram_Type
                        | E_Anonymous_Access_Protected_Subprogram_Type
          and then
        Ekind (Type_2) in E_Anonymous_Access_Subprogram_Type
                        | E_Anonymous_Access_Protected_Subprogram_Type;

      --  Test anonymous access type case. For this case, static subtype
      --  matching is required for mode conformance (RM 6.3.1(15)). We check
      --  the base types because we may have built internal subtype entities
      --  to handle null-excluding types (see Process_Formals).

      if (Ekind (Base_Type (Type_1)) = E_Anonymous_Access_Type
            and then
          Ekind (Base_Type (Type_2)) = E_Anonymous_Access_Type)

        -- Ada 2005 (AI-254)

        or else Are_Anonymous_Access_To_Subprogram_Types
      then
         declare
            Desig_1 : Entity_Id;
            Desig_2 : Entity_Id;

         begin
            --  In Ada 2005, access constant indicators must match for
            --  subtype conformance.

            if Ada_Version >= Ada_2005
              and then Ctype >= Subtype_Conformant
              and then
                Is_Access_Constant (Type_1) /= Is_Access_Constant (Type_2)
            then
               return False;
            end if;

            Desig_1 := Find_Designated_Type (Type_1);
            Desig_2 := Find_Designated_Type (Type_2);

            --  If the context is an instance association for a formal
            --  access-to-subprogram type; formal access parameter designated
            --  types require mapping because they may denote other formal
            --  parameters of the generic unit.

            if Get_Inst then
               Desig_1 := Get_Instance_Of (Desig_1);
               Desig_2 := Get_Instance_Of (Desig_2);
            end if;

            --  It is possible for a Class_Wide_Type to be introduced for an
            --  incomplete type, in which case there is a separate class_ wide
            --  type for the full view. The types conform if their Etypes
            --  conform, i.e. one may be the full view of the other. This can
            --  only happen in the context of an access parameter, other uses
            --  of an incomplete Class_Wide_Type are illegal.

            if Is_Class_Wide_Type (Desig_1)
                 and then
               Is_Class_Wide_Type (Desig_2)
            then
               return
                 Conforming_Types
                   (Etype (Base_Type (Desig_1)),
                    Etype (Base_Type (Desig_2)), Ctype);

            elsif Are_Anonymous_Access_To_Subprogram_Types then
               if Ada_Version < Ada_2005 then
                  return
                    Ctype = Type_Conformant
                      or else Subtypes_Statically_Match (Desig_1, Desig_2);

               --  We must check the conformance of the signatures themselves

               else
                  declare
                     Conformant : Boolean;
                  begin
                     Check_Conformance
                       (Desig_1, Desig_2, Ctype, False, Conformant);
                     return Conformant;
                  end;
               end if;

            --  A limited view of an actual matches the corresponding
            --  incomplete formal.

            elsif Ekind (Desig_2) = E_Incomplete_Subtype
              and then From_Limited_With (Desig_2)
              and then Used_As_Generic_Actual (Etype (Desig_2))
            then
               return True;

            else
               return Base_Type (Desig_1) = Base_Type (Desig_2)
                and then (Ctype = Type_Conformant
                           or else
                             Subtypes_Statically_Match (Desig_1, Desig_2));
            end if;
         end;

      --  Otherwise definitely no match

      else
         if ((Ekind (Type_1) = E_Anonymous_Access_Type
               and then Is_Access_Type (Type_2))
            or else (Ekind (Type_2) = E_Anonymous_Access_Type
                      and then Is_Access_Type (Type_1)))
           and then
             Conforming_Types
               (Designated_Type (Type_1), Designated_Type (Type_2), Ctype)
         then
            May_Hide_Profile := True;
         end if;

         return False;
      end if;
   end Conforming_Types;

   --------------------------
   -- Create_Extra_Formals --
   --------------------------

   procedure Create_Extra_Formals (E : Entity_Id) is
      First_Extra : Entity_Id := Empty;
      Formal      : Entity_Id;
      Last_Extra  : Entity_Id := Empty;

      function Add_Extra_Formal
        (Assoc_Entity : Entity_Id;
         Typ          : Entity_Id;
         Scope        : Entity_Id;
         Suffix       : String) return Entity_Id;
      --  Add an extra formal to the current list of formals and extra formals.
      --  The extra formal is added to the end of the list of extra formals,
      --  and also returned as the result. These formals are always of mode IN.
      --  The new formal has the type Typ, is declared in Scope, and its name
      --  is given by a concatenation of the name of Assoc_Entity and Suffix.
      --  The following suffixes are currently used. They should not be changed
      --  without coordinating with CodePeer, which makes use of these to
      --  provide better messages.

      --  O denotes the Constrained bit.
      --  L denotes the accessibility level.
      --  BIP_xxx denotes an extra formal for a build-in-place function. See
      --  the full list in exp_ch6.BIP_Formal_Kind.

      ----------------------
      -- Add_Extra_Formal --
      ----------------------

      function Add_Extra_Formal
        (Assoc_Entity : Entity_Id;
         Typ          : Entity_Id;
         Scope        : Entity_Id;
         Suffix       : String) return Entity_Id
      is
         EF : constant Entity_Id :=
                Make_Defining_Identifier (Sloc (Assoc_Entity),
                  Chars  => New_External_Name (Chars (Assoc_Entity),
                                               Suffix => Suffix));

      begin
         --  A little optimization. Never generate an extra formal for the
         --  _init operand of an initialization procedure, since it could
         --  never be used.

         if Chars (Formal) = Name_uInit then
            return Empty;
         end if;

         Mutate_Ekind        (EF, E_In_Parameter);
         Set_Actual_Subtype  (EF, Typ);
         Set_Etype           (EF, Typ);
         Set_Scope           (EF, Scope);
         Set_Mechanism       (EF, Default_Mechanism);
         Set_Formal_Validity (EF);

         if No (First_Extra) then
            First_Extra := EF;
            Set_Extra_Formals (Scope, EF);
         end if;

         if Present (Last_Extra) then
            Set_Extra_Formal (Last_Extra, EF);
         end if;

         Last_Extra := EF;

         return EF;
      end Add_Extra_Formal;

      --  Local variables

      Formal_Type : Entity_Id;
      P_Formal    : Entity_Id := Empty;

   --  Start of processing for Create_Extra_Formals

   begin
      --  We never generate extra formals if expansion is not active because we
      --  don't need them unless we are generating code.

      if not Expander_Active then
         return;
      end if;

      --  No need to generate extra formals in interface thunks whose target
      --  primitive has no extra formals.

      if Is_Thunk (E) and then No (Extra_Formals (Thunk_Entity (E))) then
         return;
      end if;

      --  If this is a derived subprogram then the subtypes of the parent
      --  subprogram's formal parameters will be used to determine the need
      --  for extra formals.

      if Is_Overloadable (E) and then Present (Alias (E)) then
         P_Formal := First_Formal (Alias (E));
      end if;

      Formal := First_Formal (E);
      while Present (Formal) loop
         Last_Extra := Formal;
         Next_Formal (Formal);
      end loop;

      --  If Extra_Formals were already created, don't do it again. This
      --  situation may arise for subprogram types created as part of
      --  dispatching calls (see Expand_Dispatching_Call).

      if Present (Last_Extra) and then Present (Extra_Formal (Last_Extra)) then
         return;
      end if;

      --  If the subprogram is a predefined dispatching subprogram then don't
      --  generate any extra constrained or accessibility level formals. In
      --  general we suppress these for internal subprograms (by not calling
      --  Freeze_Subprogram and Create_Extra_Formals at all), but internally
      --  generated stream attributes do get passed through because extra
      --  build-in-place formals are needed in some cases (limited 'Input).

      if Is_Predefined_Internal_Operation (E) then
         goto Test_For_Func_Result_Extras;
      end if;

      Formal := First_Formal (E);
      while Present (Formal) loop

         --  Create extra formal for supporting the attribute 'Constrained.
         --  The case of a private type view without discriminants also
         --  requires the extra formal if the underlying type has defaulted
         --  discriminants.

         if Ekind (Formal) /= E_In_Parameter then
            if Present (P_Formal) then
               Formal_Type := Etype (P_Formal);
            else
               Formal_Type := Etype (Formal);
            end if;

            --  Do not produce extra formals for Unchecked_Union parameters.
            --  Jump directly to the end of the loop.

            if Is_Unchecked_Union (Base_Type (Formal_Type)) then
               goto Skip_Extra_Formal_Generation;
            end if;

            if not Has_Discriminants (Formal_Type)
              and then Ekind (Formal_Type) in Private_Kind
              and then Present (Underlying_Type (Formal_Type))
            then
               Formal_Type := Underlying_Type (Formal_Type);
            end if;

            --  Suppress the extra formal if formal's subtype is constrained or
            --  indefinite, or we're compiling for Ada 2012 and the underlying
            --  type is tagged and limited. In Ada 2012, a limited tagged type
            --  can have defaulted discriminants, but 'Constrained is required
            --  to return True, so the formal is never needed (see AI05-0214).
            --  Note that this ensures consistency of calling sequences for
            --  dispatching operations when some types in a class have defaults
            --  on discriminants and others do not (and requiring the extra
            --  formal would introduce distributed overhead).

            --  If the type does not have a completion yet, treat as prior to
            --  Ada 2012 for consistency.

            if Has_Discriminants (Formal_Type)
              and then not Is_Constrained (Formal_Type)
              and then Is_Definite_Subtype (Formal_Type)
              and then (Ada_Version < Ada_2012
                         or else No (Underlying_Type (Formal_Type))
                         or else not
                           (Is_Limited_Type (Formal_Type)
                             and then
                               (Is_Tagged_Type
                                  (Underlying_Type (Formal_Type)))))
            then
               Set_Extra_Constrained
                 (Formal, Add_Extra_Formal (Formal, Standard_Boolean, E, "O"));
            end if;
         end if;

         --  Create extra formal for supporting accessibility checking. This
         --  is done for both anonymous access formals and formals of named
         --  access types that are marked as controlling formals. The latter
         --  case can occur when Expand_Dispatching_Call creates a subprogram
         --  type and substitutes the types of access-to-class-wide actuals
         --  for the anonymous access-to-specific-type of controlling formals.
         --  Base_Type is applied because in cases where there is a null
         --  exclusion the formal may have an access subtype.

         --  This is suppressed if we specifically suppress accessibility
         --  checks at the package level for either the subprogram, or the
         --  package in which it resides. However, we do not suppress it
         --  simply if the scope has accessibility checks suppressed, since
         --  this could cause trouble when clients are compiled with a
         --  different suppression setting. The explicit checks at the
         --  package level are safe from this point of view.

         if (Ekind (Base_Type (Etype (Formal))) = E_Anonymous_Access_Type
              or else (Is_Controlling_Formal (Formal)
                        and then Is_Access_Type (Base_Type (Etype (Formal)))))
           and then not
             (Explicit_Suppress (E, Accessibility_Check)
               or else
              Explicit_Suppress (Scope (E), Accessibility_Check))
           and then
             (No (P_Formal)
               or else Present (Extra_Accessibility (P_Formal)))
         then
            Set_Extra_Accessibility
              (Formal, Add_Extra_Formal (Formal, Standard_Natural, E, "L"));
         end if;

         --  This label is required when skipping extra formal generation for
         --  Unchecked_Union parameters.

         <<Skip_Extra_Formal_Generation>>

         if Present (P_Formal) then
            Next_Formal (P_Formal);
         end if;

         Next_Formal (Formal);
      end loop;

      <<Test_For_Func_Result_Extras>>

      --  Ada 2012 (AI05-234): "the accessibility level of the result of a
      --  function call is ... determined by the point of call ...".

      if Needs_Result_Accessibility_Level (E) then
         Set_Extra_Accessibility_Of_Result
           (E, Add_Extra_Formal (E, Standard_Natural, E, "L"));
      end if;

      --  Ada 2005 (AI-318-02): In the case of build-in-place functions, add
      --  appropriate extra formals. See type Exp_Ch6.BIP_Formal_Kind.

      if Is_Build_In_Place_Function (E) then
         declare
            Result_Subt : constant Entity_Id := Etype (E);
            Formal_Typ  : Entity_Id;
            Subp_Decl   : Node_Id;
            Discard     : Entity_Id;

         begin
            --  In the case of functions with unconstrained result subtypes,
            --  add a 4-state formal indicating whether the return object is
            --  allocated by the caller (1), or should be allocated by the
            --  callee on the secondary stack (2), in the global heap (3), or
            --  in a user-defined storage pool (4). For the moment we just use
            --  Natural for the type of this formal. Note that this formal
            --  isn't usually needed in the case where the result subtype is
            --  constrained, but it is needed when the function has a tagged
            --  result, because generally such functions can be called in a
            --  dispatching context and such calls must be handled like calls
            --  to a class-wide function.

            if Needs_BIP_Alloc_Form (E) then
               Discard :=
                 Add_Extra_Formal
                   (E, Standard_Natural,
                    E, BIP_Formal_Suffix (BIP_Alloc_Form));

               --  Add BIP_Storage_Pool, in case BIP_Alloc_Form indicates to
               --  use a user-defined pool. This formal is not added on
               --  ZFP as those targets do not support pools.

               if RTE_Available (RE_Root_Storage_Pool_Ptr) then
                  Discard :=
                    Add_Extra_Formal
                      (E, RTE (RE_Root_Storage_Pool_Ptr),
                       E, BIP_Formal_Suffix (BIP_Storage_Pool));
               end if;
            end if;

            --  In the case of functions whose result type needs finalization,
            --  add an extra formal which represents the finalization master.

            if Needs_BIP_Finalization_Master (E) then
               Discard :=
                 Add_Extra_Formal
                   (E, RTE (RE_Finalization_Master_Ptr),
                    E, BIP_Formal_Suffix (BIP_Finalization_Master));
            end if;

            --  When the result type contains tasks, add two extra formals: the
            --  master of the tasks to be created, and the caller's activation
            --  chain.

            if Needs_BIP_Task_Actuals (E) then
               Discard :=
                 Add_Extra_Formal
                   (E, RTE (RE_Master_Id),
                    E, BIP_Formal_Suffix (BIP_Task_Master));

               Set_Has_Master_Entity (E);

               Discard :=
                 Add_Extra_Formal
                   (E, RTE (RE_Activation_Chain_Access),
                    E, BIP_Formal_Suffix (BIP_Activation_Chain));
            end if;

            --  All build-in-place functions get an extra formal that will be
            --  passed the address of the return object within the caller.

            Formal_Typ :=
              Create_Itype (E_Anonymous_Access_Type, E, Scope_Id => Scope (E));

            --  Incomplete_View_From_Limited_With is needed here because
            --  gigi gets confused if the designated type is the full view
            --  coming from a limited-with'ed package. In the normal case,
            --  (no limited with) Incomplete_View_From_Limited_With
            --  returns Result_Subt.

            Set_Directly_Designated_Type
              (Formal_Typ, Incomplete_View_From_Limited_With (Result_Subt));
            Set_Etype (Formal_Typ, Formal_Typ);
            Set_Depends_On_Private
              (Formal_Typ, Has_Private_Component (Formal_Typ));
            Set_Is_Public (Formal_Typ, Is_Public (Scope (Formal_Typ)));
            Set_Is_Access_Constant (Formal_Typ, False);

            --  Ada 2005 (AI-50217): Propagate the attribute that indicates
            --  the designated type comes from the limited view (for back-end
            --  purposes).

            Set_From_Limited_With
              (Formal_Typ, From_Limited_With (Result_Subt));

            Layout_Type (Formal_Typ);

            --  Force the definition of the Itype in case of internal function
            --  calls within the same or nested scope.

            if Is_Subprogram_Or_Generic_Subprogram (E) then
               Subp_Decl := Parent (E);

               --  The insertion point for an Itype reference should be after
               --  the unit declaration node of the subprogram. An exception
               --  to this are inherited operations from a parent type in which
               --  case the derived type acts as their parent.

               if Nkind (Subp_Decl) in N_Function_Specification
                                     | N_Procedure_Specification
               then
                  Subp_Decl := Parent (Subp_Decl);
               end if;

               Build_Itype_Reference (Formal_Typ, Subp_Decl);
            end if;

            Discard :=
              Add_Extra_Formal
                (E, Formal_Typ, E, BIP_Formal_Suffix (BIP_Object_Access));
         end;
      end if;

      --  If this is an instance of a generic, we need to have extra formals
      --  for the Alias.

      if Is_Generic_Instance (E) and then Present (Alias (E)) then
         Set_Extra_Formals (Alias (E), Extra_Formals (E));
      end if;
   end Create_Extra_Formals;

   -----------------------------
   -- Enter_Overloaded_Entity --
   -----------------------------

   procedure Enter_Overloaded_Entity (S : Entity_Id) is
      function Matches_Predefined_Op return Boolean;
      --  This returns an approximation of whether S matches a predefined
      --  operator, based on the operator symbol, and the parameter and result
      --  types. The rules are scattered throughout chapter 4 of the Ada RM.

      ---------------------------
      -- Matches_Predefined_Op --
      ---------------------------

      function Matches_Predefined_Op return Boolean is
         Formal_1    : constant Entity_Id := First_Formal (S);
         Formal_2    : constant Entity_Id := Next_Formal (Formal_1);
         Op          : constant Name_Id   := Chars (S);
         Result_Type : constant Entity_Id := Base_Type (Etype (S));
         Type_1      : constant Entity_Id := Base_Type (Etype (Formal_1));

      begin
         --  Binary operator

         if Present (Formal_2) then
            declare
               Type_2 : constant Entity_Id := Base_Type (Etype (Formal_2));

            begin
               --  All but "&" and "**" have same-types parameters

               case Op is
                  when Name_Op_Concat
                     | Name_Op_Expon
                  =>
                     null;

                  when others =>
                     if Type_1 /= Type_2 then
                        return False;
                     end if;
               end case;

               --  Check parameter and result types

               case Op is
                  when Name_Op_And
                     | Name_Op_Or
                     | Name_Op_Xor
                  =>
                     return
                       Is_Boolean_Type (Result_Type)
                         and then Result_Type = Type_1;

                  when Name_Op_Mod
                     | Name_Op_Rem
                  =>
                     return
                       Is_Integer_Type (Result_Type)
                         and then Result_Type = Type_1;

                  when Name_Op_Add
                     | Name_Op_Divide
                     | Name_Op_Multiply
                     | Name_Op_Subtract
                  =>
                     return
                       Is_Numeric_Type (Result_Type)
                         and then Result_Type = Type_1;

                  when Name_Op_Eq
                     | Name_Op_Ne
                  =>
                     return
                       Is_Boolean_Type (Result_Type)
                         and then not Is_Limited_Type (Type_1);

                  when Name_Op_Ge
                     | Name_Op_Gt
                     | Name_Op_Le
                     | Name_Op_Lt
                  =>
                     return
                       Is_Boolean_Type (Result_Type)
                         and then (Is_Array_Type (Type_1)
                                    or else Is_Scalar_Type (Type_1));

                  when Name_Op_Concat =>
                     return Is_Array_Type (Result_Type);

                  when Name_Op_Expon =>
                     return
                       (Is_Integer_Type (Result_Type)
                           or else Is_Floating_Point_Type (Result_Type))
                         and then Result_Type = Type_1
                         and then Type_2 = Standard_Integer;

                  when others =>
                     raise Program_Error;
               end case;
            end;

         --  Unary operator

         else
            case Op is
               when Name_Op_Abs
                  | Name_Op_Add
                  | Name_Op_Subtract
               =>
                  return
                    Is_Numeric_Type (Result_Type)
                      and then Result_Type = Type_1;

               when Name_Op_Not =>
                  return
                    Is_Boolean_Type (Result_Type)
                      and then Result_Type = Type_1;

               when others =>
                  raise Program_Error;
            end case;
         end if;
      end Matches_Predefined_Op;

      --  Local variables

      E   : Entity_Id := Current_Entity_In_Scope (S);
      C_E : Entity_Id := Current_Entity (S);

   --  Start of processing for Enter_Overloaded_Entity

   begin
      if Present (E) then
         Set_Has_Homonym (E);
         Set_Has_Homonym (S);
      end if;

      Set_Is_Immediately_Visible (S);
      Set_Scope (S, Current_Scope);

      --  Chain new entity if front of homonym in current scope, so that
      --  homonyms are contiguous.

      if Present (E) and then E /= C_E then
         while Homonym (C_E) /= E loop
            C_E := Homonym (C_E);
         end loop;

         Set_Homonym (C_E, S);

      else
         E := C_E;
         Set_Current_Entity (S);
      end if;

      Set_Homonym (S, E);

      if Is_Inherited_Operation (S) then
         Append_Inherited_Subprogram (S);
      else
         Append_Entity (S, Current_Scope);
      end if;

      Set_Public_Status (S);

      if Debug_Flag_E then
         Write_Str ("New overloaded entity chain: ");
         Write_Name (Chars (S));

         E := S;
         while Present (E) loop
            Write_Str (" "); Write_Int (Int (E));
            E := Homonym (E);
         end loop;

         Write_Eol;
      end if;

      --  Generate warning for hiding

      if Warn_On_Hiding
        and then Comes_From_Source (S)
        and then In_Extended_Main_Source_Unit (S)
      then
         E := S;
         loop
            E := Homonym (E);
            exit when No (E);

            --  Warn unless genuine overloading. Do not emit warning on
            --  hiding predefined operators in Standard (these are either an
            --  artifact of our implicit declarations, or simple noise) but
            --  keep warning on a operator defined on a local subtype, because
            --  of the real danger that different operators may be applied in
            --  various parts of the program.

            --  Note that if E and S have the same scope, there is never any
            --  hiding. Either the two conflict, and the program is illegal,
            --  or S is overriding an implicit inherited subprogram.

            if Scope (E) /= Scope (S)
              and then (not Is_Overloadable (E)
                         or else Subtype_Conformant (E, S))
              and then (Is_Immediately_Visible (E)
                         or else Is_Potentially_Use_Visible (S))
            then
               if Scope (E) = Standard_Standard then
                  if Nkind (S) = N_Defining_Operator_Symbol
                    and then Scope (Base_Type (Etype (First_Formal (S)))) /=
                               Scope (S)
                    and then Matches_Predefined_Op
                  then
                     Error_Msg_N
                       ("declaration of & hides predefined operator?h?", S);
                  end if;

               --  E not immediately within Standard

               else
                  Error_Msg_Sloc := Sloc (E);
                  Error_Msg_N ("declaration of & hides one #?h?", S);
               end if;
            end if;
         end loop;
      end if;
   end Enter_Overloaded_Entity;

   -----------------------------
   -- Check_Untagged_Equality --
   -----------------------------

   procedure Check_Untagged_Equality (Eq_Op : Entity_Id) is
      Typ      : constant Entity_Id := Etype (First_Formal (Eq_Op));
      Decl     : constant Node_Id   := Unit_Declaration_Node (Eq_Op);
      Obj_Decl : Node_Id;

   begin
      --  This check applies only if we have a subprogram declaration with an
      --  untagged record type that is conformant to the predefined op.

      if Nkind (Decl) /= N_Subprogram_Declaration
        or else not Is_Record_Type (Typ)
        or else Is_Tagged_Type (Typ)
        or else Etype (Next_Formal (First_Formal (Eq_Op))) /= Typ
      then
         return;
      end if;

      --  In Ada 2012 case, we will output errors or warnings depending on
      --  the setting of debug flag -gnatd.E.

      if Ada_Version >= Ada_2012 then
         Error_Msg_Warn := Debug_Flag_Dot_EE;

      --  In earlier versions of Ada, nothing to do unless we are warning on
      --  Ada 2012 incompatibilities (Warn_On_Ada_2012_Incompatibility set).

      else
         if not Warn_On_Ada_2012_Compatibility then
            return;
         end if;
      end if;

      --  Cases where the type has already been frozen

      if Is_Frozen (Typ) then

         --  The check applies to a primitive operation, so check that type
         --  and equality operation are in the same scope.

         if Scope (Typ) /= Current_Scope then
            return;

         --  If the type is a generic actual (sub)type, the operation is not
         --  primitive either because the base type is declared elsewhere.

         elsif Is_Generic_Actual_Type (Typ) then
            return;

         --  Here we have a definite error of declaration after freezing

         else
            if Ada_Version >= Ada_2012 then
               Error_Msg_NE
                 ("equality operator must be declared before type & is "
                  & "frozen (RM 4.5.2 (9.8)) (Ada 2012)<<", Eq_Op, Typ);

               --  In Ada 2012 mode with error turned to warning, output one
               --  more warning to warn that the equality operation may not
               --  compose. This is the consequence of ignoring the error.

               if Error_Msg_Warn then
                  Error_Msg_N ("\equality operation may not compose??", Eq_Op);
               end if;

            else
               Error_Msg_NE
                 ("equality operator must be declared before type& is "
                  & "frozen (RM 4.5.2 (9.8)) (Ada 2012)?y?", Eq_Op, Typ);
            end if;

            --  If we are in the package body, we could just move the
            --  declaration to the package spec, so add a message saying that.

            if In_Package_Body (Scope (Typ)) then
               if Ada_Version >= Ada_2012 then
                  Error_Msg_N
                    ("\move declaration to package spec<<", Eq_Op);
               else
                  Error_Msg_N
                    ("\move declaration to package spec (Ada 2012)?y?", Eq_Op);
               end if;

            --  Otherwise try to find the freezing point for better message.

            else
               Obj_Decl := Next (Parent (Typ));
               while Present (Obj_Decl) and then Obj_Decl /= Decl loop
                  if Nkind (Obj_Decl) = N_Object_Declaration
                    and then Etype (Defining_Identifier (Obj_Decl)) = Typ
                  then
                     --  Freezing point, output warnings

                     if Ada_Version >= Ada_2012 then
                        Error_Msg_NE
                          ("type& is frozen by declaration??", Obj_Decl, Typ);
                        Error_Msg_N
                          ("\an equality operator cannot be declared after "
                           & "this point??",
                           Obj_Decl);
                     else
                        Error_Msg_NE
                          ("type& is frozen by declaration (Ada 2012)?y?",
                           Obj_Decl, Typ);
                        Error_Msg_N
                          ("\an equality operator cannot be declared after "
                           & "this point (Ada 2012)?y?",
                           Obj_Decl);
                     end if;

                     exit;

                  --  If we reach generated code for subprogram declaration
                  --  or body, it is the body that froze the type and the
                  --  declaration is legal.

                  elsif Sloc (Obj_Decl) = Sloc (Decl) then
                     return;
                  end if;

                  Next (Obj_Decl);
               end loop;
            end if;
         end if;

      --  Here if type is not frozen yet. It is illegal to have a primitive
      --  equality declared in the private part if the type is visible.

      elsif not In_Same_List (Parent (Typ), Decl)
        and then not Is_Limited_Type (Typ)
      then
         --  Shouldn't we give an RM reference here???

         if Ada_Version >= Ada_2012 then
            Error_Msg_N
              ("equality operator appears too late<<", Eq_Op);
         else
            Error_Msg_N
              ("equality operator appears too late (Ada 2012)?y?", Eq_Op);
         end if;

      --  Finally check for AI12-0352: declaration of a user-defined primitive
      --  equality operation for a record type T is illegal if it occurs after
      --  a type has been derived from T.

      else
         Obj_Decl := Next (Parent (Typ));

         while Present (Obj_Decl) and then Obj_Decl /= Decl loop
            if Nkind (Obj_Decl) = N_Full_Type_Declaration
              and then Etype (Defining_Identifier (Obj_Decl)) = Typ
            then
               Error_Msg_N
                 ("equality operator cannot appear after derivation", Eq_Op);
               Error_Msg_NE
                 ("an equality operator for& cannot be declared after "
                  & "this point??",
                  Obj_Decl, Typ);
            end if;

            Next (Obj_Decl);
         end loop;
      end if;
   end Check_Untagged_Equality;

   -----------------------------
   -- Find_Corresponding_Spec --
   -----------------------------

   function Find_Corresponding_Spec
     (N          : Node_Id;
      Post_Error : Boolean := True) return Entity_Id
   is
      Spec       : constant Node_Id   := Specification (N);
      Designator : constant Entity_Id := Defining_Entity (Spec);

      E : Entity_Id;

      function Different_Generic_Profile (E : Entity_Id) return Boolean;
      --  Even if fully conformant, a body may depend on a generic actual when
      --  the spec does not, or vice versa, in which case they were distinct
      --  entities in the generic.

      -------------------------------
      -- Different_Generic_Profile --
      -------------------------------

      function Different_Generic_Profile (E : Entity_Id) return Boolean is
         F1, F2 : Entity_Id;

         function Same_Generic_Actual (T1, T2 : Entity_Id) return Boolean;
         --  Check that the types of corresponding formals have the same
         --  generic actual if any. We have to account for subtypes of a
         --  generic formal, declared between a spec and a body, which may
         --  appear distinct in an instance but matched in the generic, and
         --  the subtype may be used either in the spec or the body of the
         --  subprogram being checked.

         -------------------------
         -- Same_Generic_Actual --
         -------------------------

         function Same_Generic_Actual (T1, T2 : Entity_Id) return Boolean is

            function Is_Declared_Subtype (S1, S2 : Entity_Id) return Boolean;
            --  Predicate to check whether S1 is a subtype of S2 in the source
            --  of the instance.

            -------------------------
            -- Is_Declared_Subtype --
            -------------------------

            function Is_Declared_Subtype (S1, S2 : Entity_Id) return Boolean is
            begin
               return Comes_From_Source (Parent (S1))
                 and then Nkind (Parent (S1)) = N_Subtype_Declaration
                 and then Is_Entity_Name (Subtype_Indication (Parent (S1)))
                 and then Entity (Subtype_Indication (Parent (S1))) = S2;
            end Is_Declared_Subtype;

         --  Start of processing for Same_Generic_Actual

         begin
            return Is_Generic_Actual_Type (T1) = Is_Generic_Actual_Type (T2)
              or else Is_Declared_Subtype (T1, T2)
              or else Is_Declared_Subtype (T2, T1);
         end Same_Generic_Actual;

      --  Start of processing for Different_Generic_Profile

      begin
         if not In_Instance then
            return False;

         elsif Ekind (E) = E_Function
           and then not Same_Generic_Actual (Etype (E), Etype (Designator))
         then
            return True;
         end if;

         F1 := First_Formal (Designator);
         F2 := First_Formal (E);
         while Present (F1) loop
            if not Same_Generic_Actual (Etype (F1), Etype (F2)) then
               return True;
            end if;

            Next_Formal (F1);
            Next_Formal (F2);
         end loop;

         return False;
      end Different_Generic_Profile;

   --  Start of processing for Find_Corresponding_Spec

   begin
      E := Current_Entity (Designator);
      while Present (E) loop

         --  We are looking for a matching spec. It must have the same scope,
         --  and the same name, and either be type conformant, or be the case
         --  of a library procedure spec and its body (which belong to one
         --  another regardless of whether they are type conformant or not).

         if Scope (E) = Current_Scope then
            if Current_Scope = Standard_Standard
              or else (Ekind (E) = Ekind (Designator)
                        and then Type_Conformant (E, Designator))
            then
               --  Within an instantiation, we know that spec and body are
               --  subtype conformant, because they were subtype conformant in
               --  the generic. We choose the subtype-conformant entity here as
               --  well, to resolve spurious ambiguities in the instance that
               --  were not present in the generic (i.e. when two different
               --  types are given the same actual). If we are looking for a
               --  spec to match a body, full conformance is expected.

               if In_Instance then

                  --  Inherit the convention and "ghostness" of the matching
                  --  spec to ensure proper full and subtype conformance.

                  Set_Convention (Designator, Convention (E));

                  --  Skip past subprogram bodies and subprogram renamings that
                  --  may appear to have a matching spec, but that aren't fully
                  --  conformant with it. That can occur in cases where an
                  --  actual type causes unrelated homographs in the instance.

                  if Nkind (N) in N_Subprogram_Body
                                | N_Subprogram_Renaming_Declaration
                    and then Present (Homonym (E))
                    and then not Fully_Conformant (Designator, E)
                  then
                     goto Next_Entity;

                  elsif not Subtype_Conformant (Designator, E) then
                     goto Next_Entity;

                  elsif Different_Generic_Profile (E) then
                     goto Next_Entity;
                  end if;
               end if;

               --  Ada 2012 (AI05-0165): For internally generated bodies of
               --  null procedures locate the internally generated spec. We
               --  enforce mode conformance since a tagged type may inherit
               --  from interfaces several null primitives which differ only
               --  in the mode of the formals.

               if not (Comes_From_Source (E))
                 and then Is_Null_Procedure (E)
                 and then not Mode_Conformant (Designator, E)
               then
                  null;

               --  For null procedures coming from source that are completions,
               --  analysis of the generated body will establish the link.

               elsif Comes_From_Source (E)
                 and then Nkind (Spec) = N_Procedure_Specification
                 and then Null_Present (Spec)
               then
                  return E;

               --  Expression functions can be completions, but cannot be
               --  completed by an explicit body.

               elsif Comes_From_Source (E)
                 and then Comes_From_Source (N)
                 and then Nkind (N) = N_Subprogram_Body
                 and then Nkind (Original_Node (Unit_Declaration_Node (E))) =
                            N_Expression_Function
               then
                  Error_Msg_Sloc := Sloc (E);
                  Error_Msg_N ("body conflicts with expression function#", N);
                  return Empty;

               elsif not Has_Completion (E) then
                  if Nkind (N) /= N_Subprogram_Body_Stub then
                     Set_Corresponding_Spec (N, E);
                  end if;

                  Set_Has_Completion (E);
                  return E;

               elsif Nkind (Parent (N)) = N_Subunit then

                  --  If this is the proper body of a subunit, the completion
                  --  flag is set when analyzing the stub.

                  return E;

               --  If E is an internal function with a controlling result that
               --  was created for an operation inherited by a null extension,
               --  it may be overridden by a body without a previous spec (one
               --  more reason why these should be shunned). In that case we
               --  remove the generated body if present, because the current
               --  one is the explicit overriding.

               elsif Ekind (E) = E_Function
                 and then Ada_Version >= Ada_2005
                 and then not Comes_From_Source (E)
                 and then Has_Controlling_Result (E)
                 and then Is_Null_Extension (Etype (E))
                 and then Comes_From_Source (Spec)
               then
                  Set_Has_Completion (E, False);

                  if Expander_Active
                    and then Nkind (Parent (E)) = N_Function_Specification
                  then
                     Remove
                       (Unit_Declaration_Node
                          (Corresponding_Body (Unit_Declaration_Node (E))));

                     return E;

                  --  If expansion is disabled, or if the wrapper function has
                  --  not been generated yet, this a late body overriding an
                  --  inherited operation, or it is an overriding by some other
                  --  declaration before the controlling result is frozen. In
                  --  either case this is a declaration of a new entity.

                  else
                     return Empty;
                  end if;

               --  If the body already exists, then this is an error unless
               --  the previous declaration is the implicit declaration of a
               --  derived subprogram. It is also legal for an instance to
               --  contain type conformant overloadable declarations (but the
               --  generic declaration may not), per 8.3(26/2).

               elsif No (Alias (E))
                 and then not Is_Intrinsic_Subprogram (E)
                 and then not In_Instance
                 and then Post_Error
               then
                  Error_Msg_Sloc := Sloc (E);

                  if Is_Imported (E) then
                     Error_Msg_NE
                      ("body not allowed for imported subprogram & declared#",
                        N, E);
                  else
                     Error_Msg_NE ("duplicate body for & declared#", N, E);
                  end if;
               end if;

            --  Child units cannot be overloaded, so a conformance mismatch
            --  between body and a previous spec is an error.

            elsif Is_Child_Unit (E)
              and then
                Nkind (Unit_Declaration_Node (Designator)) = N_Subprogram_Body
              and then
                Nkind (Parent (Unit_Declaration_Node (Designator))) =
                  N_Compilation_Unit
              and then Post_Error
            then
               Error_Msg_N
                 ("body of child unit does not match previous declaration", N);
            end if;
         end if;

         <<Next_Entity>>
            E := Homonym (E);
      end loop;

      --  On exit, we know that no previous declaration of subprogram exists

      return Empty;
   end Find_Corresponding_Spec;

   ----------------------
   -- Fully_Conformant --
   ----------------------

   function Fully_Conformant (New_Id, Old_Id : Entity_Id) return Boolean is
      Result : Boolean;
   begin
      Check_Conformance (New_Id, Old_Id, Fully_Conformant, False, Result);
      return Result;
   end Fully_Conformant;

   ----------------------------------
   -- Fully_Conformant_Expressions --
   ----------------------------------

   function Fully_Conformant_Expressions
     (Given_E1 : Node_Id;
      Given_E2 : Node_Id;
      Report   : Boolean := False) return Boolean
   is
      E1 : constant Node_Id := Original_Node (Given_E1);
      E2 : constant Node_Id := Original_Node (Given_E2);
      --  We always test conformance on original nodes, since it is possible
      --  for analysis and/or expansion to make things look as though they
      --  conform when they do not, e.g. by converting 1+2 into 3.

      function FCE (Given_E1 : Node_Id; Given_E2 : Node_Id) return Boolean;
      --  ???

      function FCL (L1 : List_Id; L2 : List_Id) return Boolean;
      --  Compare elements of two lists for conformance. Elements have to be
      --  conformant, and actuals inserted as default parameters do not match
      --  explicit actuals with the same value.

      function FCO (Op_Node : Node_Id; Call_Node : Node_Id) return Boolean;
      --  Compare an operator node with a function call

      ---------
      -- FCE --
      ---------

      function FCE (Given_E1 : Node_Id; Given_E2 : Node_Id) return Boolean is
      begin
         return Fully_Conformant_Expressions (Given_E1, Given_E2, Report);
      end FCE;

      ---------
      -- FCL --
      ---------

      function FCL (L1 : List_Id; L2 : List_Id) return Boolean is
         N1 : Node_Id;
         N2 : Node_Id;

      begin
         if L1 = No_List then
            N1 := Empty;
         else
            N1 := First (L1);
         end if;

         if L2 = No_List then
            N2 := Empty;
         else
            N2 := First (L2);
         end if;

         --  Compare two lists, skipping rewrite insertions (we want to compare
         --  the original trees, not the expanded versions).

         loop
            if Is_Rewrite_Insertion (N1) then
               Next (N1);
            elsif Is_Rewrite_Insertion (N2) then
               Next (N2);
            elsif No (N1) then
               return No (N2);
            elsif No (N2) then
               return False;
            elsif not FCE (N1, N2) then
               return False;
            else
               Next (N1);
               Next (N2);
            end if;
         end loop;
      end FCL;

      ---------
      -- FCO --
      ---------

      function FCO (Op_Node : Node_Id; Call_Node : Node_Id) return Boolean is
         Actuals : constant List_Id := Parameter_Associations (Call_Node);
         Act     : Node_Id;

      begin
         if No (Actuals)
            or else Entity (Op_Node) /= Entity (Name (Call_Node))
         then
            return False;

         else
            Act := First (Actuals);

            if Nkind (Op_Node) in N_Binary_Op then
               if not FCE (Left_Opnd (Op_Node), Act) then
                  return False;
               end if;

               Next (Act);
            end if;

            return Present (Act)
              and then FCE (Right_Opnd (Op_Node), Act)
              and then No (Next (Act));
         end if;
      end FCO;

      function User_Defined_Numeric_Literal_Mismatch return Boolean;
      --  Usually literals with the same value like 12345 and 12_345
      --  or 123.0 and 123.00 conform, but not if they are
      --  user-defined literals.

      -------------------------------------------
      -- User_Defined_Numeric_Literal_Mismatch --
      -------------------------------------------

      function User_Defined_Numeric_Literal_Mismatch return Boolean is
         E1_Is_User_Defined : constant Boolean :=
           Nkind (Given_E1) not in N_Integer_Literal | N_Real_Literal;
         E2_Is_User_Defined : constant Boolean :=
           Nkind (Given_E2) not in N_Integer_Literal | N_Real_Literal;

      begin
         pragma Assert (E1_Is_User_Defined = E2_Is_User_Defined);

         return E1_Is_User_Defined and then
           not String_Equal (String_From_Numeric_Literal (E1),
                             String_From_Numeric_Literal (E2));
      end User_Defined_Numeric_Literal_Mismatch;

      --  Local variables

      Result : Boolean;

   --  Start of processing for Fully_Conformant_Expressions

   begin
      Result := True;

      --  Nonconformant if paren count does not match. Note: if some idiot
      --  complains that we don't do this right for more than 3 levels of
      --  parentheses, they will be treated with the respect they deserve.

      if Paren_Count (E1) /= Paren_Count (E2) then
         return False;

      --  If same entities are referenced, then they are conformant even if
      --  they have different forms (RM 8.3.1(19-20)).

      elsif Is_Entity_Name (E1) and then Is_Entity_Name (E2) then
         if Present (Entity (E1)) then
            Result := Entity (E1) = Entity (E2)

              --  One may be a discriminant that has been replaced by the
              --  corresponding discriminal.

              or else
                (Chars (Entity (E1)) = Chars (Entity (E2))
                  and then Ekind (Entity (E1)) = E_Discriminant
                  and then Ekind (Entity (E2)) = E_In_Parameter)

             --  The discriminant of a protected type is transformed into
             --  a local constant and then into a parameter of a protected
             --  operation.

             or else
               (Ekind (Entity (E1)) = E_Constant
                 and then Ekind (Entity (E2)) = E_In_Parameter
                 and then Present (Discriminal_Link (Entity (E1)))
                 and then Discriminal_Link (Entity (E1)) =
                          Discriminal_Link (Entity (E2)))

             --  AI12-050: The loop variables of quantified expressions match
             --  if they have the same identifier, even though they may have
             --  different entities.

              or else
                (Chars (Entity (E1)) = Chars (Entity (E2))
                  and then Ekind (Entity (E1)) = E_Loop_Parameter
                  and then Ekind (Entity (E2)) = E_Loop_Parameter)

              --  A call to an instantiation of Unchecked_Conversion is
              --  rewritten with the name of the generated function created for
              --  the instance, and this must be special-cased.

              or else
                 (Ekind (Entity (E1)) = E_Function
                   and then Is_Intrinsic_Subprogram (Entity (E1))
                   and then Is_Generic_Instance (Entity (E1))
                   and then Entity (E2) = Alias (Entity (E1)));
            if Report and not Result then
               Error_Msg_Sloc :=
                 Text_Ptr'Max (Sloc (Entity (E1)), Sloc (Entity (E2)));
               Error_Msg_NE
                 ("meaning of& differs because of declaration#", E1, E2);
            end if;

            return Result;

         elsif Nkind (E1) = N_Expanded_Name
           and then Nkind (E2) = N_Expanded_Name
           and then Nkind (Selector_Name (E1)) = N_Character_Literal
           and then Nkind (Selector_Name (E2)) = N_Character_Literal
         then
            return Chars (Selector_Name (E1)) = Chars (Selector_Name (E2));

         else
            --  Identifiers in component associations don't always have
            --  entities, but their names must conform.

            return Nkind  (E1) = N_Identifier
              and then Nkind (E2) = N_Identifier
              and then Chars (E1) = Chars (E2);
         end if;

      elsif Nkind (E1) = N_Character_Literal
        and then Nkind (E2) = N_Expanded_Name
      then
         return Nkind (Selector_Name (E2)) = N_Character_Literal
           and then Chars (E1) = Chars (Selector_Name (E2));

      elsif Nkind (E2) = N_Character_Literal
        and then Nkind (E1) = N_Expanded_Name
      then
         return Nkind (Selector_Name (E1)) = N_Character_Literal
           and then Chars (E2) = Chars (Selector_Name (E1));

      elsif Nkind (E1) in N_Op and then Nkind (E2) = N_Function_Call then
         return FCO (E1, E2);

      elsif Nkind (E2) in N_Op and then Nkind (E1) = N_Function_Call then
         return FCO (E2, E1);

      --  Otherwise we must have the same syntactic entity

      elsif Nkind (E1) /= Nkind (E2) then
         return False;

      --  At this point, we specialize by node type

      else
         case Nkind (E1) is
            when N_Aggregate =>
               return
                 FCL (Expressions (E1), Expressions (E2))
                   and then
                 FCL (Component_Associations (E1),
                      Component_Associations (E2));

            when N_Allocator =>
               if Nkind (Expression (E1)) = N_Qualified_Expression
                    or else
                  Nkind (Expression (E2)) = N_Qualified_Expression
               then
                  return FCE (Expression (E1), Expression (E2));

               --  Check that the subtype marks and any constraints
               --  are conformant

               else
                  declare
                     Indic1 : constant Node_Id := Expression (E1);
                     Indic2 : constant Node_Id := Expression (E2);
                     Elt1   : Node_Id;
                     Elt2   : Node_Id;

                  begin
                     if Nkind (Indic1) /= N_Subtype_Indication then
                        return
                          Nkind (Indic2) /= N_Subtype_Indication
                            and then Entity (Indic1) = Entity (Indic2);

                     elsif Nkind (Indic2) /= N_Subtype_Indication then
                        return
                          Nkind (Indic1) /= N_Subtype_Indication
                            and then Entity (Indic1) = Entity (Indic2);

                     else
                        if Entity (Subtype_Mark (Indic1)) /=
                          Entity (Subtype_Mark (Indic2))
                        then
                           return False;
                        end if;

                        Elt1 := First (Constraints (Constraint (Indic1)));
                        Elt2 := First (Constraints (Constraint (Indic2)));
                        while Present (Elt1) and then Present (Elt2) loop
                           if not FCE (Elt1, Elt2) then
                              return False;
                           end if;

                           Next (Elt1);
                           Next (Elt2);
                        end loop;

                        return True;
                     end if;
                  end;
               end if;

            when N_Attribute_Reference =>
               return
                 Attribute_Name (E1) = Attribute_Name (E2)
                   and then FCL (Expressions (E1), Expressions (E2));

            when N_Binary_Op =>
               return
                 Entity (E1) = Entity (E2)
                   and then FCE (Left_Opnd  (E1), Left_Opnd  (E2))
                   and then FCE (Right_Opnd (E1), Right_Opnd (E2));

            when N_Membership_Test
               | N_Short_Circuit
            =>
               return
                 FCE (Left_Opnd  (E1), Left_Opnd  (E2))
                   and then
                 FCE (Right_Opnd (E1), Right_Opnd (E2));

            when N_Case_Expression =>
               declare
                  Alt1 : Node_Id;
                  Alt2 : Node_Id;

               begin
                  if not FCE (Expression (E1), Expression (E2)) then
                     return False;

                  else
                     Alt1 := First (Alternatives (E1));
                     Alt2 := First (Alternatives (E2));
                     loop
                        if Present (Alt1) /= Present (Alt2) then
                           return False;
                        elsif No (Alt1) then
                           return True;
                        end if;

                        if not FCE (Expression (Alt1), Expression (Alt2))
                          or else not FCL (Discrete_Choices (Alt1),
                                           Discrete_Choices (Alt2))
                        then
                           return False;
                        end if;

                        Next (Alt1);
                        Next (Alt2);
                     end loop;
                  end if;
               end;

            when N_Character_Literal =>
               return
                 Char_Literal_Value (E1) = Char_Literal_Value (E2);

            when N_Component_Association =>
               return
                 FCL (Choices (E1), Choices (E2))
                   and then
                 FCE (Expression (E1), Expression (E2));

            when N_Explicit_Dereference =>
               return
                 FCE (Prefix (E1), Prefix (E2));

            when N_Extension_Aggregate =>
               return
                 FCL (Expressions (E1), Expressions (E2))
                   and then Null_Record_Present (E1) =
                            Null_Record_Present (E2)
                   and then FCL (Component_Associations (E1),
                               Component_Associations (E2));

            when N_Function_Call =>
               return
                 FCE (Name (E1), Name (E2))
                   and then
                 FCL (Parameter_Associations (E1),
                      Parameter_Associations (E2));

            when N_If_Expression =>
               return
                 FCL (Expressions (E1), Expressions (E2));

            when N_Indexed_Component =>
               return
                 FCE (Prefix (E1), Prefix (E2))
                   and then
                 FCL (Expressions (E1), Expressions (E2));

            when N_Integer_Literal =>
               return (Intval (E1) = Intval (E2))
                 and then not User_Defined_Numeric_Literal_Mismatch;

            when N_Null =>
               return True;

            when N_Operator_Symbol =>
               return
                 Chars (E1) = Chars (E2);

            when N_Others_Choice =>
               return True;

            when N_Parameter_Association =>
               return
                 Chars (Selector_Name (E1)) = Chars (Selector_Name (E2))
                   and then FCE (Explicit_Actual_Parameter (E1),
                                 Explicit_Actual_Parameter (E2));

            when N_Qualified_Expression
               | N_Type_Conversion
               | N_Unchecked_Type_Conversion
            =>
               return
                 FCE (Subtype_Mark (E1), Subtype_Mark (E2))
                   and then
                 FCE (Expression (E1), Expression (E2));

            when N_Quantified_Expression =>
               if not FCE (Condition (E1), Condition (E2)) then
                  return False;
               end if;

               if Present (Loop_Parameter_Specification (E1))
                 and then Present (Loop_Parameter_Specification (E2))
               then
                  declare
                     L1 : constant Node_Id :=
                       Loop_Parameter_Specification (E1);
                     L2 : constant Node_Id :=
                       Loop_Parameter_Specification (E2);

                  begin
                     return
                       Reverse_Present (L1) = Reverse_Present (L2)
                         and then
                           FCE (Defining_Identifier (L1),
                                Defining_Identifier (L2))
                         and then
                           FCE (Discrete_Subtype_Definition (L1),
                                Discrete_Subtype_Definition (L2));
                  end;

               elsif Present (Iterator_Specification (E1))
                 and then Present (Iterator_Specification (E2))
               then
                  declare
                     I1 : constant Node_Id := Iterator_Specification (E1);
                     I2 : constant Node_Id := Iterator_Specification (E2);

                  begin
                     return
                       FCE (Defining_Identifier (I1),
                            Defining_Identifier (I2))
                       and then
                         Of_Present (I1) = Of_Present (I2)
                       and then
                         Reverse_Present (I1) = Reverse_Present (I2)
                       and then FCE (Name (I1), Name (I2))
                       and then FCE (Subtype_Indication (I1),
                                      Subtype_Indication (I2));
                  end;

               --  The quantified expressions used different specifications to
               --  walk their respective ranges.

               else
                  return False;
               end if;

            when N_Range =>
               return
                 FCE (Low_Bound (E1), Low_Bound (E2))
                   and then
                 FCE (High_Bound (E1), High_Bound (E2));

            when N_Real_Literal =>
               return (Realval (E1) = Realval (E2))
                 and then not User_Defined_Numeric_Literal_Mismatch;

            when N_Selected_Component =>
               return
                 FCE (Prefix (E1), Prefix (E2))
                   and then
                 FCE (Selector_Name (E1), Selector_Name (E2));

            when N_Slice =>
               return
                 FCE (Prefix (E1), Prefix (E2))
                   and then
                 FCE (Discrete_Range (E1), Discrete_Range (E2));

            when N_String_Literal =>
               declare
                  S1 : constant String_Id := Strval (E1);
                  S2 : constant String_Id := Strval (E2);
                  L1 : constant Nat       := String_Length (S1);
                  L2 : constant Nat       := String_Length (S2);

               begin
                  if L1 /= L2 then
                     return False;

                  else
                     for J in 1 .. L1 loop
                        if Get_String_Char (S1, J) /=
                           Get_String_Char (S2, J)
                        then
                           return False;
                        end if;
                     end loop;

                     return True;
                  end if;
               end;

            when N_Unary_Op =>
               return
                 Entity (E1) = Entity (E2)
                   and then
                 FCE (Right_Opnd (E1), Right_Opnd (E2));

            --  All other node types cannot appear in this context. Strictly
            --  we should raise a fatal internal error. Instead we just ignore
            --  the nodes. This means that if anyone makes a mistake in the
            --  expander and mucks an expression tree irretrievably, the result
            --  will be a failure to detect a (probably very obscure) case
            --  of non-conformance, which is better than bombing on some
            --  case where two expressions do in fact conform.

            when others =>
               return True;
         end case;
      end if;
   end Fully_Conformant_Expressions;

   ----------------------------------------
   -- Fully_Conformant_Discrete_Subtypes --
   ----------------------------------------

   function Fully_Conformant_Discrete_Subtypes
     (Given_S1 : Node_Id;
      Given_S2 : Node_Id) return Boolean
   is
      S1 : constant Node_Id := Original_Node (Given_S1);
      S2 : constant Node_Id := Original_Node (Given_S2);

      function Conforming_Bounds (B1, B2 : Node_Id) return Boolean;
      --  Special-case for a bound given by a discriminant, which in the body
      --  is replaced with the discriminal of the enclosing type.

      function Conforming_Ranges (R1, R2 : Node_Id) return Boolean;
      --  Check both bounds

      -----------------------
      -- Conforming_Bounds --
      -----------------------

      function Conforming_Bounds (B1, B2 : Node_Id) return Boolean is
      begin
         if Is_Entity_Name (B1)
           and then Is_Entity_Name (B2)
           and then Ekind (Entity (B1)) = E_Discriminant
         then
            return Chars (B1) = Chars (B2);

         else
            return Fully_Conformant_Expressions (B1, B2);
         end if;
      end Conforming_Bounds;

      -----------------------
      -- Conforming_Ranges --
      -----------------------

      function Conforming_Ranges (R1, R2 : Node_Id) return Boolean is
      begin
         return
           Conforming_Bounds (Low_Bound (R1), Low_Bound (R2))
             and then
           Conforming_Bounds (High_Bound (R1), High_Bound (R2));
      end Conforming_Ranges;

   --  Start of processing for Fully_Conformant_Discrete_Subtypes

   begin
      if Nkind (S1) /= Nkind (S2) then
         return False;

      elsif Is_Entity_Name (S1) then
         return Entity (S1) = Entity (S2);

      elsif Nkind (S1) = N_Range then
         return Conforming_Ranges (S1, S2);

      elsif Nkind (S1) = N_Subtype_Indication then
         return
            Entity (Subtype_Mark (S1)) = Entity (Subtype_Mark (S2))
              and then
            Conforming_Ranges
              (Range_Expression (Constraint (S1)),
               Range_Expression (Constraint (S2)));
      else
         return True;
      end if;
   end Fully_Conformant_Discrete_Subtypes;

   --------------------
   -- Install_Entity --
   --------------------

   procedure Install_Entity (E : Entity_Id) is
      Prev : constant Entity_Id := Current_Entity (E);
   begin
      Set_Is_Immediately_Visible (E);
      Set_Current_Entity (E);
      Set_Homonym (E, Prev);
   end Install_Entity;

   ---------------------
   -- Install_Formals --
   ---------------------

   procedure Install_Formals (Id : Entity_Id) is
      F : Entity_Id;
   begin
      F := First_Formal (Id);
      while Present (F) loop
         Install_Entity (F);
         Next_Formal (F);
      end loop;
   end Install_Formals;

   -----------------------------
   -- Is_Interface_Conformant --
   -----------------------------

   function Is_Interface_Conformant
     (Tagged_Type : Entity_Id;
      Iface_Prim  : Entity_Id;
      Prim        : Entity_Id) return Boolean
   is
      --  The operation may in fact be an inherited (implicit) operation
      --  rather than the original interface primitive, so retrieve the
      --  ultimate ancestor.

      Iface : constant Entity_Id :=
                Find_Dispatching_Type (Ultimate_Alias (Iface_Prim));
      Typ   : constant Entity_Id := Find_Dispatching_Type (Prim);

      function Controlling_Formal (Prim : Entity_Id) return Entity_Id;
      --  Return the controlling formal of Prim

      ------------------------
      -- Controlling_Formal --
      ------------------------

      function Controlling_Formal (Prim : Entity_Id) return Entity_Id is
         E : Entity_Id;

      begin
         E := First_Entity (Prim);
         while Present (E) loop
            if Is_Formal (E) and then Is_Controlling_Formal (E) then
               return E;
            end if;

            Next_Entity (E);
         end loop;

         return Empty;
      end Controlling_Formal;

      --  Local variables

      Iface_Ctrl_F : constant Entity_Id := Controlling_Formal (Iface_Prim);
      Prim_Ctrl_F  : constant Entity_Id := Controlling_Formal (Prim);

   --  Start of processing for Is_Interface_Conformant

   begin
      pragma Assert (Is_Subprogram (Iface_Prim)
        and then Is_Subprogram (Prim)
        and then Is_Dispatching_Operation (Iface_Prim)
        and then Is_Dispatching_Operation (Prim));

      pragma Assert (Is_Interface (Iface)
        or else (Present (Alias (Iface_Prim))
                   and then
                     Is_Interface
                       (Find_Dispatching_Type (Ultimate_Alias (Iface_Prim)))));

      if Prim = Iface_Prim
        or else not Is_Subprogram (Prim)
        or else Ekind (Prim) /= Ekind (Iface_Prim)
        or else not Is_Dispatching_Operation (Prim)
        or else Scope (Prim) /= Scope (Tagged_Type)
        or else No (Typ)
        or else Base_Type (Typ) /= Base_Type (Tagged_Type)
        or else not Primitive_Names_Match (Iface_Prim, Prim)
      then
         return False;

      --  The mode of the controlling formals must match

      elsif Present (Iface_Ctrl_F)
        and then Present (Prim_Ctrl_F)
        and then Ekind (Iface_Ctrl_F) /= Ekind (Prim_Ctrl_F)
      then
         return False;

      --  Case of a procedure, or a function whose result type matches the
      --  result type of the interface primitive, or a function that has no
      --  controlling result (I or access I).

      elsif Ekind (Iface_Prim) = E_Procedure
        or else Etype (Prim) = Etype (Iface_Prim)
        or else not Has_Controlling_Result (Prim)
      then
         return Type_Conformant
                  (Iface_Prim, Prim, Skip_Controlling_Formals => True);

      --  Case of a function returning an interface, or an access to one. Check
      --  that the return types correspond.

      elsif Implements_Interface (Typ, Iface) then
         if (Ekind (Etype (Prim)) = E_Anonymous_Access_Type)
              /=
            (Ekind (Etype (Iface_Prim)) = E_Anonymous_Access_Type)
         then
            return False;
         else
            return
              Type_Conformant (Prim, Ultimate_Alias (Iface_Prim),
                Skip_Controlling_Formals => True);
         end if;

      else
         return False;
      end if;
   end Is_Interface_Conformant;

   ---------------------------------
   -- Is_Non_Overriding_Operation --
   ---------------------------------

   function Is_Non_Overriding_Operation
     (Prev_E : Entity_Id;
      New_E  : Entity_Id) return Boolean
   is
      Formal : Entity_Id;
      F_Typ  : Entity_Id;
      G_Typ  : Entity_Id := Empty;

      function Get_Generic_Parent_Type (F_Typ : Entity_Id) return Entity_Id;
      --  If F_Type is a derived type associated with a generic actual subtype,
      --  then return its Generic_Parent_Type attribute, else return Empty.

      function Types_Correspond
        (P_Type : Entity_Id;
         N_Type : Entity_Id) return Boolean;
      --  Returns true if and only if the types (or designated types in the
      --  case of anonymous access types) are the same or N_Type is derived
      --  directly or indirectly from P_Type.

      -----------------------------
      -- Get_Generic_Parent_Type --
      -----------------------------

      function Get_Generic_Parent_Type (F_Typ : Entity_Id) return Entity_Id is
         G_Typ : Entity_Id;
         Defn  : Node_Id;
         Indic : Node_Id;

      begin
         if Is_Derived_Type (F_Typ)
           and then Nkind (Parent (F_Typ)) = N_Full_Type_Declaration
         then
            --  The tree must be traversed to determine the parent subtype in
            --  the generic unit, which unfortunately isn't always available
            --  via semantic attributes. ??? (Note: The use of Original_Node
            --  is needed for cases where a full derived type has been
            --  rewritten.)

            --  If the parent type is a scalar type, the derivation creates
            --  an anonymous base type for it, and the source type is its
            --  first subtype.

            if Is_Scalar_Type (F_Typ)
              and then not Comes_From_Source (F_Typ)
            then
               Defn :=
                 Type_Definition
                   (Original_Node (Parent (First_Subtype (F_Typ))));
            else
               Defn := Type_Definition (Original_Node (Parent (F_Typ)));
            end if;
            if Nkind (Defn) = N_Derived_Type_Definition then
               Indic := Subtype_Indication (Defn);

               if Nkind (Indic) = N_Subtype_Indication then
                  G_Typ := Entity (Subtype_Mark (Indic));
               else
                  G_Typ := Entity (Indic);
               end if;

               if Nkind (Parent (G_Typ)) = N_Subtype_Declaration
                 and then Present (Generic_Parent_Type (Parent (G_Typ)))
               then
                  return Generic_Parent_Type (Parent (G_Typ));
               end if;
            end if;
         end if;

         return Empty;
      end Get_Generic_Parent_Type;

      ----------------------
      -- Types_Correspond --
      ----------------------

      function Types_Correspond
        (P_Type : Entity_Id;
         N_Type : Entity_Id) return Boolean
      is
         Prev_Type : Entity_Id := Base_Type (P_Type);
         New_Type  : Entity_Id := Base_Type (N_Type);

      begin
         if Ekind (Prev_Type) = E_Anonymous_Access_Type then
            Prev_Type := Designated_Type (Prev_Type);
         end if;

         if Ekind (New_Type) = E_Anonymous_Access_Type then
            New_Type := Designated_Type (New_Type);
         end if;

         if Prev_Type = New_Type then
            return True;

         elsif not Is_Class_Wide_Type (New_Type) then
            while Etype (New_Type) /= New_Type loop
               New_Type := Etype (New_Type);

               if New_Type = Prev_Type then
                  return True;
               end if;
            end loop;
         end if;
         return False;
      end Types_Correspond;

   --  Start of processing for Is_Non_Overriding_Operation

   begin
      --  In the case where both operations are implicit derived subprograms
      --  then neither overrides the other. This can only occur in certain
      --  obscure cases (e.g., derivation from homographs created in a generic
      --  instantiation).

      if Present (Alias (Prev_E)) and then Present (Alias (New_E)) then
         return True;

      elsif Ekind (Current_Scope) = E_Package
        and then Is_Generic_Instance (Current_Scope)
        and then In_Private_Part (Current_Scope)
        and then Comes_From_Source (New_E)
      then
         --  We examine the formals and result type of the inherited operation,
         --  to determine whether their type is derived from (the instance of)
         --  a generic type. The first such formal or result type is the one
         --  tested.

         Formal := First_Formal (Prev_E);
         F_Typ  := Empty;
         while Present (Formal) loop
            F_Typ := Base_Type (Etype (Formal));

            if Ekind (F_Typ) = E_Anonymous_Access_Type then
               F_Typ := Designated_Type (F_Typ);
            end if;

            G_Typ := Get_Generic_Parent_Type (F_Typ);
            exit when Present (G_Typ);

            Next_Formal (Formal);
         end loop;

         --  If the function dispatches on result check the result type

         if No (G_Typ) and then Ekind (Prev_E) = E_Function then
            G_Typ := Get_Generic_Parent_Type (Base_Type (Etype (Prev_E)));
         end if;

         if No (G_Typ) then
            return False;
         end if;

         --  If the generic type is a private type, then the original operation
         --  was not overriding in the generic, because there was no primitive
         --  operation to override.

         if Nkind (Parent (G_Typ)) = N_Formal_Type_Declaration
           and then Nkind (Formal_Type_Definition (Parent (G_Typ))) =
                      N_Formal_Private_Type_Definition
         then
            return True;

         --  The generic parent type is the ancestor of a formal derived
         --  type declaration. We need to check whether it has a primitive
         --  operation that should be overridden by New_E in the generic.

         else
            declare
               P_Formal : Entity_Id;
               N_Formal : Entity_Id;
               P_Typ    : Entity_Id;
               N_Typ    : Entity_Id;
               P_Prim   : Entity_Id;
               Prim_Elt : Elmt_Id := First_Elmt (Primitive_Operations (G_Typ));

            begin
               while Present (Prim_Elt) loop
                  P_Prim := Node (Prim_Elt);

                  if Chars (P_Prim) = Chars (New_E)
                    and then Ekind (P_Prim) = Ekind (New_E)
                  then
                     P_Formal := First_Formal (P_Prim);
                     N_Formal := First_Formal (New_E);
                     while Present (P_Formal) and then Present (N_Formal) loop
                        P_Typ := Etype (P_Formal);
                        N_Typ := Etype (N_Formal);

                        if not Types_Correspond (P_Typ, N_Typ) then
                           exit;
                        end if;

                        Next_Formal (P_Formal);
                        Next_Formal (N_Formal);
                     end loop;

                     --  Found a matching primitive operation belonging to the
                     --  formal ancestor type, so the new subprogram is
                     --  overriding.

                     if No (P_Formal)
                       and then No (N_Formal)
                       and then (Ekind (New_E) /= E_Function
                                  or else
                                    Types_Correspond
                                      (Etype (P_Prim), Etype (New_E)))
                     then
                        return False;
                     end if;
                  end if;

                  Next_Elmt (Prim_Elt);
               end loop;

               --  If no match found, then the new subprogram does not override
               --  in the generic (nor in the instance).

               --  If the type in question is not abstract, and the subprogram
               --  is, this will be an error if the new operation is in the
               --  private part of the instance. Emit a warning now, which will
               --  make the subsequent error message easier to understand.

               if Present (F_Typ) and then not Is_Abstract_Type (F_Typ)
                 and then Is_Abstract_Subprogram (Prev_E)
                 and then In_Private_Part (Current_Scope)
               then
                  Error_Msg_Node_2 := F_Typ;
                  Error_Msg_NE
                    ("private operation& in generic unit does not override "
                     & "any primitive operation of& (RM 12.3 (18))??",
                     New_E, New_E);
               end if;

               return True;
            end;
         end if;
      else
         return False;
      end if;
   end Is_Non_Overriding_Operation;

   -------------------------------------
   -- List_Inherited_Pre_Post_Aspects --
   -------------------------------------

   procedure List_Inherited_Pre_Post_Aspects (E : Entity_Id) is
   begin
      if Opt.List_Inherited_Aspects
        and then Is_Subprogram_Or_Generic_Subprogram (E)
      then
         declare
            Subps : constant Subprogram_List := Inherited_Subprograms (E);
            Items : Node_Id;
            Prag  : Node_Id;

         begin
            for Index in Subps'Range loop
               Items := Contract (Subps (Index));

               if Present (Items) then
                  Prag := Pre_Post_Conditions (Items);
                  while Present (Prag) loop
                     Error_Msg_Sloc := Sloc (Prag);

                     if Class_Present (Prag)
                       and then not Split_PPC (Prag)
                     then
                        if Pragma_Name (Prag) = Name_Precondition then
                           Error_Msg_N
                             ("info: & inherits `Pre''Class` aspect from "
                              & "#?L?", E);
                        else
                           Error_Msg_N
                             ("info: & inherits `Post''Class` aspect from "
                              & "#?L?", E);
                        end if;
                     end if;

                     Prag := Next_Pragma (Prag);
                  end loop;
               end if;
            end loop;
         end;
      end if;
   end List_Inherited_Pre_Post_Aspects;

   ------------------------------
   -- Make_Inequality_Operator --
   ------------------------------

   --  S is the defining identifier of an equality operator. We build a
   --  subprogram declaration with the right signature. This operation is
   --  intrinsic, because it is always expanded as the negation of the
   --  call to the equality function.

   procedure Make_Inequality_Operator (S : Entity_Id) is
      Loc     : constant Source_Ptr := Sloc (S);
      Decl    : Node_Id;
      Formals : List_Id;
      Op_Name : Entity_Id;

      FF : constant Entity_Id := First_Formal (S);
      NF : constant Entity_Id := Next_Formal (FF);

   begin
      --  Check that equality was properly defined, ignore call if not

      if No (NF) then
         return;
      end if;

      declare
         A : constant Entity_Id :=
               Make_Defining_Identifier (Sloc (FF),
                 Chars => Chars (FF));

         B : constant Entity_Id :=
               Make_Defining_Identifier (Sloc (NF),
                 Chars => Chars (NF));

      begin
         Op_Name := Make_Defining_Operator_Symbol (Loc, Name_Op_Ne);

         Formals := New_List (
           Make_Parameter_Specification (Loc,
             Defining_Identifier => A,
             Parameter_Type      =>
               New_Occurrence_Of (Etype (First_Formal (S)),
                 Sloc (Etype (First_Formal (S))))),

           Make_Parameter_Specification (Loc,
             Defining_Identifier => B,
             Parameter_Type      =>
               New_Occurrence_Of (Etype (Next_Formal (First_Formal (S))),
                 Sloc (Etype (Next_Formal (First_Formal (S)))))));

         Decl :=
           Make_Subprogram_Declaration (Loc,
             Specification =>
               Make_Function_Specification (Loc,
                 Defining_Unit_Name       => Op_Name,
                 Parameter_Specifications => Formals,
                 Result_Definition        =>
                   New_Occurrence_Of (Standard_Boolean, Loc)));

         --  Insert inequality right after equality if it is explicit or after
         --  the derived type when implicit. These entities are created only
         --  for visibility purposes, and eventually replaced in the course
         --  of expansion, so they do not need to be attached to the tree and
         --  seen by the back-end. Keeping them internal also avoids spurious
         --  freezing problems. The declaration is inserted in the tree for
         --  analysis, and removed afterwards. If the equality operator comes
         --  from an explicit declaration, attach the inequality immediately
         --  after. Else the equality is inherited from a derived type
         --  declaration, so insert inequality after that declaration.

         if No (Alias (S)) then
            Insert_After (Unit_Declaration_Node (S), Decl);
         elsif Is_List_Member (Parent (S)) then
            Insert_After (Parent (S), Decl);
         else
            Insert_After (Parent (Etype (First_Formal (S))), Decl);
         end if;

         Mark_Rewrite_Insertion (Decl);
         Set_Is_Intrinsic_Subprogram (Op_Name);
         Analyze (Decl);
         Remove (Decl);
         Set_Has_Completion (Op_Name);
         Set_Corresponding_Equality (Op_Name, S);
         Set_Is_Abstract_Subprogram (Op_Name, Is_Abstract_Subprogram (S));
      end;
   end Make_Inequality_Operator;

   ----------------------
   -- May_Need_Actuals --
   ----------------------

   procedure May_Need_Actuals (Fun : Entity_Id) is
      F : Entity_Id;
      B : Boolean;

   begin
      F := First_Formal (Fun);
      B := True;
      while Present (F) loop
         if No (Default_Value (F)) then
            B := False;
            exit;
         end if;

         Next_Formal (F);
      end loop;

      Set_Needs_No_Actuals (Fun, B);
   end May_Need_Actuals;

   ---------------------
   -- Mode_Conformant --
   ---------------------

   function Mode_Conformant (New_Id, Old_Id : Entity_Id) return Boolean is
      Result : Boolean;
   begin
      Check_Conformance (New_Id, Old_Id, Mode_Conformant, False, Result);
      return Result;
   end Mode_Conformant;

   ---------------------------
   -- New_Overloaded_Entity --
   ---------------------------

   procedure New_Overloaded_Entity
     (S            : Entity_Id;
      Derived_Type : Entity_Id := Empty)
   is
      Overridden_Subp : Entity_Id := Empty;
      --  Set if the current scope has an operation that is type-conformant
      --  with S, and becomes hidden by S.

      Is_Primitive_Subp : Boolean;
      --  Set to True if the new subprogram is primitive

      E : Entity_Id;
      --  Entity that S overrides

      procedure Check_For_Primitive_Subprogram
        (Is_Primitive  : out Boolean;
         Is_Overriding : Boolean := False);
      --  If the subprogram being analyzed is a primitive operation of the type
      --  of a formal or result, set the Has_Primitive_Operations flag on the
      --  type, and set Is_Primitive to True (otherwise set to False). Set the
      --  corresponding flag on the entity itself for later use.

      function Has_Matching_Entry_Or_Subprogram (E : Entity_Id) return Boolean;
      --  True if a) E is a subprogram whose first formal is a concurrent type
      --  defined in the scope of E that has some entry or subprogram whose
      --  profile matches E, or b) E is an internally built dispatching
      --  subprogram of a protected type and there is a matching subprogram
      --  defined in the enclosing scope of the protected type, or c) E is
      --  an entry of a synchronized type and a matching procedure has been
      --  previously defined in the enclosing scope of the synchronized type.

      function Is_Private_Declaration (E : Entity_Id) return Boolean;
      --  Check that E is declared in the private part of the current package,
      --  or in the package body, where it may hide a previous declaration.
      --  We can't use In_Private_Part by itself because this flag is also
      --  set when freezing entities, so we must examine the place of the
      --  declaration in the tree, and recognize wrapper packages as well.

      function Is_Overriding_Alias
        (Old_E : Entity_Id;
         New_E : Entity_Id) return Boolean;
      --  Check whether new subprogram and old subprogram are both inherited
      --  from subprograms that have distinct dispatch table entries. This can
      --  occur with derivations from instances with accidental homonyms. The
      --  function is conservative given that the converse is only true within
      --  instances that contain accidental overloadings.

      procedure Report_Conflict (S : Entity_Id; E : Entity_Id);
      --  Report conflict between entities S and E

      ------------------------------------
      -- Check_For_Primitive_Subprogram --
      ------------------------------------

      procedure Check_For_Primitive_Subprogram
        (Is_Primitive  : out Boolean;
         Is_Overriding : Boolean := False)
      is
         Formal : Entity_Id;
         F_Typ  : Entity_Id;
         B_Typ  : Entity_Id;

         function Visible_Part_Type (T : Entity_Id) return Boolean;
         --  Returns true if T is declared in the visible part of the current
         --  package scope; otherwise returns false. Assumes that T is declared
         --  in a package.

         procedure Check_Private_Overriding (T : Entity_Id);
         --  Checks that if a primitive abstract subprogram of a visible
         --  abstract type is declared in a private part, then it must override
         --  an abstract subprogram declared in the visible part. Also checks
         --  that if a primitive function with a controlling result is declared
         --  in a private part, then it must override a function declared in
         --  the visible part.

         ------------------------------
         -- Check_Private_Overriding --
         ------------------------------

         procedure Check_Private_Overriding (T : Entity_Id) is
            function Overrides_Private_Part_Op return Boolean;
            --  This detects the special case where the overriding subprogram
            --  is overriding a subprogram that was declared in the same
            --  private part. That case is illegal by 3.9.3(10).

            function Overrides_Visible_Function
              (Partial_View : Entity_Id) return Boolean;
            --  True if S overrides a function in the visible part. The
            --  overridden function could be explicitly or implicitly declared.

            -------------------------------
            -- Overrides_Private_Part_Op --
            -------------------------------

            function Overrides_Private_Part_Op return Boolean is
               Over_Decl : constant Node_Id :=
                             Unit_Declaration_Node (Overridden_Operation (S));
               Subp_Decl : constant Node_Id := Unit_Declaration_Node (S);

            begin
               pragma Assert (Is_Overriding);
               pragma Assert
                 (Nkind (Over_Decl) = N_Abstract_Subprogram_Declaration);
               pragma Assert
                 (Nkind (Subp_Decl) = N_Abstract_Subprogram_Declaration);

               return In_Same_List (Over_Decl, Subp_Decl);
            end Overrides_Private_Part_Op;

            --------------------------------
            -- Overrides_Visible_Function --
            --------------------------------

            function Overrides_Visible_Function
              (Partial_View : Entity_Id) return Boolean
            is
            begin
               if not Is_Overriding or else not Has_Homonym (S) then
                  return False;
               end if;

               if not Present (Partial_View) then
                  return True;
               end if;

               --  Search through all the homonyms H of S in the current
               --  package spec, and return True if we find one that matches.
               --  Note that Parent (H) will be the declaration of the
               --  partial view of T for a match.

               declare
                  H : Entity_Id := S;
               begin
                  loop
                     H := Homonym (H);
                     exit when not Present (H) or else Scope (H) /= Scope (S);

                     if Nkind (Parent (H)) in
                        N_Private_Extension_Declaration |
                        N_Private_Type_Declaration
                       and then Defining_Identifier (Parent (H)) = Partial_View
                     then
                        return True;
                     end if;
                  end loop;
               end;

               return False;
            end Overrides_Visible_Function;

         --  Start of processing for Check_Private_Overriding

         begin
            if Is_Package_Or_Generic_Package (Current_Scope)
              and then In_Private_Part (Current_Scope)
              and then Visible_Part_Type (T)
              and then not In_Instance
            then
               if Is_Abstract_Type (T)
                 and then Is_Abstract_Subprogram (S)
                 and then (not Is_Overriding
                             or else not Is_Abstract_Subprogram (E)
                             or else Overrides_Private_Part_Op)
               then
                  Error_Msg_N
                    ("abstract subprograms must be visible (RM 3.9.3(10))!",
                     S);

               elsif Ekind (S) = E_Function then
                  declare
                     Partial_View : constant Entity_Id :=
                                      Incomplete_Or_Partial_View (T);

                  begin
                     if not Overrides_Visible_Function (Partial_View) then

                        --  Here, S is "function ... return T;" declared in
                        --  the private part, not overriding some visible
                        --  operation. That's illegal in the tagged case
                        --  (but not if the private type is untagged).

                        if ((Present (Partial_View)
                              and then Is_Tagged_Type (Partial_View))
                          or else (not Present (Partial_View)
                                    and then Is_Tagged_Type (T)))
                          and then T = Base_Type (Etype (S))
                        then
                           Error_Msg_N
                             ("private function with tagged result must"
                              & " override visible-part function", S);
                           Error_Msg_N
                             ("\move subprogram to the visible part"
                              & " (RM 3.9.3(10))", S);

                        --  Ada 2012 (AI05-0073): Extend this check to the case
                        --  of a function whose result subtype is defined by an
                        --  access_definition designating specific tagged type.

                        elsif Ekind (Etype (S)) = E_Anonymous_Access_Type
                          and then Is_Tagged_Type (Designated_Type (Etype (S)))
                          and then
                            not Is_Class_Wide_Type
                                  (Designated_Type (Etype (S)))
                          and then Ada_Version >= Ada_2012
                        then
                           Error_Msg_N
                             ("private function with controlling access "
                              & "result must override visible-part function",
                              S);
                           Error_Msg_N
                             ("\move subprogram to the visible part"
                              & " (RM 3.9.3(10))", S);
                        end if;
                     end if;
                  end;
               end if;
            end if;
         end Check_Private_Overriding;

         -----------------------
         -- Visible_Part_Type --
         -----------------------

         function Visible_Part_Type (T : Entity_Id) return Boolean is
            P : constant Node_Id := Unit_Declaration_Node (Scope (T));

         begin
            --  If the entity is a private type, then it must be declared in a
            --  visible part.

            if Ekind (T) in Private_Kind then
               return True;

            elsif Is_Type (T) and then Has_Private_Declaration (T) then
               return True;

            elsif Is_List_Member (Declaration_Node (T))
              and then List_Containing (Declaration_Node (T)) =
                         Visible_Declarations (Specification (P))
            then
               return True;

            else
               return False;
            end if;
         end Visible_Part_Type;

      --  Start of processing for Check_For_Primitive_Subprogram

      begin
         Is_Primitive := False;

         if not Comes_From_Source (S) then
            null;

         --  If subprogram is at library level, it is not primitive operation

         elsif Current_Scope = Standard_Standard then
            null;

         elsif (Is_Package_Or_Generic_Package (Current_Scope)
                 and then not In_Package_Body (Current_Scope))
           or else Is_Overriding
         then
            --  For function, check return type

            if Ekind (S) = E_Function then
               if Ekind (Etype (S)) = E_Anonymous_Access_Type then
                  F_Typ := Designated_Type (Etype (S));
               else
                  F_Typ := Etype (S);
               end if;

               B_Typ := Base_Type (F_Typ);

               if Scope (B_Typ) = Current_Scope
                 and then not Is_Class_Wide_Type (B_Typ)
                 and then not Is_Generic_Type (B_Typ)
               then
                  Is_Primitive := True;
                  Set_Has_Primitive_Operations (B_Typ);
                  Set_Is_Primitive (S);
                  Check_Private_Overriding (B_Typ);

                  --  The Ghost policy in effect at the point of declaration
                  --  or a tagged type and a primitive operation must match
                  --  (SPARK RM 6.9(16)).

                  Check_Ghost_Primitive (S, B_Typ);
               end if;
            end if;

            --  For all subprograms, check formals

            Formal := First_Formal (S);
            while Present (Formal) loop
               if Ekind (Etype (Formal)) = E_Anonymous_Access_Type then
                  F_Typ := Designated_Type (Etype (Formal));
               else
                  F_Typ := Etype (Formal);
               end if;

               B_Typ := Base_Type (F_Typ);

               if Ekind (B_Typ) = E_Access_Subtype then
                  B_Typ := Base_Type (B_Typ);
               end if;

               if Scope (B_Typ) = Current_Scope
                 and then not Is_Class_Wide_Type (B_Typ)
                 and then not Is_Generic_Type (B_Typ)
               then
                  Is_Primitive := True;
                  Set_Is_Primitive (S);
                  Set_Has_Primitive_Operations (B_Typ);
                  Check_Private_Overriding (B_Typ);

                  --  The Ghost policy in effect at the point of declaration
                  --  of a tagged type and a primitive operation must match
                  --  (SPARK RM 6.9(16)).

                  Check_Ghost_Primitive (S, B_Typ);
               end if;

               Next_Formal (Formal);
            end loop;

         --  Special case: An equality function can be redefined for a type
         --  occurring in a declarative part, and won't otherwise be treated as
         --  a primitive because it doesn't occur in a package spec and doesn't
         --  override an inherited subprogram. It's important that we mark it
         --  primitive so it can be returned by Collect_Primitive_Operations
         --  and be used in composing the equality operation of later types
         --  that have a component of the type.

         elsif Chars (S) = Name_Op_Eq
           and then Etype (S) = Standard_Boolean
         then
            B_Typ := Base_Type (Etype (First_Formal (S)));

            if Scope (B_Typ) = Current_Scope
              and then
                Base_Type (Etype (Next_Formal (First_Formal (S)))) = B_Typ
              and then not Is_Limited_Type (B_Typ)
            then
               Is_Primitive := True;
               Set_Is_Primitive (S);
               Set_Has_Primitive_Operations (B_Typ);
               Check_Private_Overriding (B_Typ);

               --  The Ghost policy in effect at the point of declaration of a
               --  tagged type and a primitive operation must match
               --  (SPARK RM 6.9(16)).

               Check_Ghost_Primitive (S, B_Typ);
            end if;
         end if;
      end Check_For_Primitive_Subprogram;

      --------------------------------------
      -- Has_Matching_Entry_Or_Subprogram --
      --------------------------------------

      function Has_Matching_Entry_Or_Subprogram
        (E : Entity_Id) return Boolean
      is
         function Check_Conforming_Parameters
           (E1_Param : Node_Id;
            E2_Param : Node_Id;
            Ctype    : Conformance_Type) return Boolean;
         --  Starting from the given parameters, check that all the parameters
         --  of two entries or subprograms are conformant. Used to skip
         --  the check on the controlling argument.

         function Matching_Entry_Or_Subprogram
           (Conc_Typ : Entity_Id;
            Subp     : Entity_Id) return Entity_Id;
         --  Return the first entry or subprogram of the given concurrent type
         --  whose name matches the name of Subp and has a profile conformant
         --  with Subp; return Empty if not found.

         function Matching_Dispatching_Subprogram
           (Conc_Typ : Entity_Id;
            Ent      : Entity_Id) return Entity_Id;
         --  Return the first dispatching primitive of Conc_Type defined in the
         --  enclosing scope of Conc_Type (i.e. before the full definition of
         --  this concurrent type) whose name matches the entry Ent and has a
         --  profile conformant with the profile of the corresponding (not yet
         --  built) dispatching primitive of Ent; return Empty if not found.

         function Matching_Original_Protected_Subprogram
           (Prot_Typ : Entity_Id;
            Subp     : Entity_Id) return Entity_Id;
         --  Return the first subprogram defined in the enclosing scope of
         --  Prot_Typ (before the full definition of this protected type)
         --  whose name matches the original name of Subp and has a profile
         --  conformant with the profile of Subp; return Empty if not found.

         function Normalized_First_Parameter_Type
           (E : Entity_Id) return Entity_Id;
         --  Return the type of the first parameter unless that type
         --  is an anonymous access type, in which case return the
         --  designated type. Used to treat anonymous-access-to-synchronized
         --  the same as synchronized for purposes of checking for
         --  prefixed view profile conflicts.

         ---------------------------------
         -- Check_Conforming_Parameters --
         ---------------------------------

         function Check_Conforming_Parameters
           (E1_Param : Node_Id;
            E2_Param : Node_Id;
            Ctype    : Conformance_Type) return Boolean
         is
            Param_E1 : Node_Id := E1_Param;
            Param_E2 : Node_Id := E2_Param;

         begin
            while Present (Param_E1) and then Present (Param_E2) loop
               if (Ctype >= Mode_Conformant) and then
                 Ekind (Defining_Identifier (Param_E1)) /=
                 Ekind (Defining_Identifier (Param_E2))
               then
                  return False;
               elsif not
                   Conforming_Types
                     (Find_Parameter_Type (Param_E1),
                      Find_Parameter_Type (Param_E2),
                      Ctype)
               then
                  return False;
               end if;

               Next (Param_E1);
               Next (Param_E2);
            end loop;

            --  The candidate is not valid if one of the two lists contains
            --  more parameters than the other

            return No (Param_E1) and then No (Param_E2);
         end Check_Conforming_Parameters;

         ----------------------------------
         -- Matching_Entry_Or_Subprogram --
         ----------------------------------

         function Matching_Entry_Or_Subprogram
           (Conc_Typ : Entity_Id;
            Subp     : Entity_Id) return Entity_Id
         is
            E : Entity_Id;

         begin
            E := First_Entity (Conc_Typ);
            while Present (E) loop
               if Chars (Subp) = Chars (E)
                 and then (Ekind (E) = E_Entry or else Is_Subprogram (E))
                 and then
                   Check_Conforming_Parameters
                     (First (Parameter_Specifications (Parent (E))),
                      Next (First (Parameter_Specifications (Parent (Subp)))),
                      Type_Conformant)
               then
                  return E;
               end if;

               Next_Entity (E);
            end loop;

            return Empty;
         end Matching_Entry_Or_Subprogram;

         -------------------------------------
         -- Matching_Dispatching_Subprogram --
         -------------------------------------

         function Matching_Dispatching_Subprogram
           (Conc_Typ : Entity_Id;
            Ent      : Entity_Id) return Entity_Id
         is
            E : Entity_Id;

         begin
            --  Search for entities in the enclosing scope of this synchonized
            --  type.

            pragma Assert (Is_Concurrent_Type (Conc_Typ));
            Push_Scope (Scope (Conc_Typ));
            E := Current_Entity_In_Scope (Ent);
            Pop_Scope;

            while Present (E) loop
               if Scope (E) = Scope (Conc_Typ)
                 and then Comes_From_Source (E)
                 and then Ekind (E) = E_Procedure
                 and then Present (First_Entity (E))
                 and then Is_Controlling_Formal (First_Entity (E))
                 and then Etype (First_Entity (E)) = Conc_Typ
                 and then
                   Check_Conforming_Parameters
                     (First (Parameter_Specifications (Parent (Ent))),
                      Next (First (Parameter_Specifications (Parent (E)))),
                      Subtype_Conformant)
               then
                  return E;
               end if;

               E := Homonym (E);
            end loop;

            return Empty;
         end Matching_Dispatching_Subprogram;

         --------------------------------------------
         -- Matching_Original_Protected_Subprogram --
         --------------------------------------------

         function Matching_Original_Protected_Subprogram
           (Prot_Typ : Entity_Id;
            Subp     : Entity_Id) return Entity_Id
         is
            ICF : constant Boolean :=
                    Is_Controlling_Formal (First_Entity (Subp));
            E   : Entity_Id;

         begin
            --  Temporarily decorate the first parameter of Subp as controlling
            --  formal, required to invoke Subtype_Conformant.

            Set_Is_Controlling_Formal (First_Entity (Subp));

            E :=
              Current_Entity_In_Scope (Original_Protected_Subprogram (Subp));

            while Present (E) loop
               if Scope (E) = Scope (Prot_Typ)
                 and then Comes_From_Source (E)
                 and then Ekind (Subp) = Ekind (E)
                 and then Present (First_Entity (E))
                 and then Is_Controlling_Formal (First_Entity (E))
                 and then Etype (First_Entity (E)) = Prot_Typ
                 and then Subtype_Conformant (Subp, E,
                            Skip_Controlling_Formals => True)
               then
                  Set_Is_Controlling_Formal (First_Entity (Subp), ICF);
                  return E;
               end if;

               E := Homonym (E);
            end loop;

            Set_Is_Controlling_Formal (First_Entity (Subp), ICF);

            return Empty;
         end Matching_Original_Protected_Subprogram;

         -------------------------------------
         -- Normalized_First_Parameter_Type --
         -------------------------------------

         function Normalized_First_Parameter_Type
           (E : Entity_Id) return Entity_Id
         is
            Result : Entity_Id := Etype (First_Entity (E));
         begin
            if Ekind (Result) = E_Anonymous_Access_Type then
               Result := Designated_Type (Result);
            end if;
            return Result;
         end Normalized_First_Parameter_Type;

      --  Start of processing for Has_Matching_Entry_Or_Subprogram

      begin
         --  Case 1: E is a subprogram whose first formal is a concurrent type
         --  defined in the scope of E that has an entry or subprogram whose
         --  profile matches E.

         if Comes_From_Source (E)
           and then Is_Subprogram (E)
           and then Present (First_Entity (E))
           and then Is_Concurrent_Record_Type
                      (Normalized_First_Parameter_Type (E))
         then
            if Scope (E) =
                 Scope (Corresponding_Concurrent_Type
                         (Normalized_First_Parameter_Type (E)))
              and then
                Present
                  (Matching_Entry_Or_Subprogram
                     (Corresponding_Concurrent_Type
                        (Normalized_First_Parameter_Type (E)),
                      Subp => E))
            then
               Report_Conflict (E,
                 Matching_Entry_Or_Subprogram
                   (Corresponding_Concurrent_Type
                      (Normalized_First_Parameter_Type (E)),
                    Subp => E));
               return True;
            end if;

         --  Case 2: E is an internally built dispatching subprogram of a
         --  protected type and there is a subprogram defined in the enclosing
         --  scope of the protected type that has the original name of E and
         --  its profile is conformant with the profile of E. We check the
         --  name of the original protected subprogram associated with E since
         --  the expander builds dispatching primitives of protected functions
         --  and procedures with other names (see Exp_Ch9.Build_Selected_Name).

         elsif not Comes_From_Source (E)
           and then Is_Subprogram (E)
           and then Present (First_Entity (E))
           and then Is_Concurrent_Record_Type (Etype (First_Entity (E)))
           and then Present (Original_Protected_Subprogram (E))
           and then
             Present
               (Matching_Original_Protected_Subprogram
                 (Corresponding_Concurrent_Type (Etype (First_Entity (E))),
                  Subp => E))
         then
            Report_Conflict (E,
              Matching_Original_Protected_Subprogram
                (Corresponding_Concurrent_Type (Etype (First_Entity (E))),
                 Subp => E));
            return True;

         --  Case 3: E is an entry of a synchronized type and a matching
         --  procedure has been previously defined in the enclosing scope
         --  of the synchronized type.

         elsif Comes_From_Source (E)
           and then Ekind (E) = E_Entry
           and then
             Present (Matching_Dispatching_Subprogram (Current_Scope, E))
         then
            Report_Conflict (E,
              Matching_Dispatching_Subprogram (Current_Scope, E));
            return True;
         end if;

         return False;
      end Has_Matching_Entry_Or_Subprogram;

      ----------------------------
      -- Is_Private_Declaration --
      ----------------------------

      function Is_Private_Declaration (E : Entity_Id) return Boolean is
         Decl       : constant Node_Id := Unit_Declaration_Node (E);
         Priv_Decls : List_Id;

      begin
         if Is_Package_Or_Generic_Package (Current_Scope)
           and then In_Private_Part (Current_Scope)
         then
            Priv_Decls :=
              Private_Declarations (Package_Specification (Current_Scope));

            return In_Package_Body (Current_Scope)
              or else
                (Is_List_Member (Decl)
                  and then List_Containing (Decl) = Priv_Decls)
              or else (Nkind (Parent (Decl)) = N_Package_Specification
                        and then not
                          Is_Compilation_Unit
                            (Defining_Entity (Parent (Decl)))
                        and then List_Containing (Parent (Parent (Decl))) =
                                                                Priv_Decls);
         else
            return False;
         end if;
      end Is_Private_Declaration;

      --------------------------
      -- Is_Overriding_Alias --
      --------------------------

      function Is_Overriding_Alias
        (Old_E : Entity_Id;
         New_E : Entity_Id) return Boolean
      is
         AO : constant Entity_Id := Alias (Old_E);
         AN : constant Entity_Id := Alias (New_E);

      begin
         return Scope (AO) /= Scope (AN)
           or else No (DTC_Entity (AO))
           or else No (DTC_Entity (AN))
           or else DT_Position (AO) = DT_Position (AN);
      end Is_Overriding_Alias;

      ---------------------
      -- Report_Conflict --
      ---------------------

      procedure Report_Conflict (S : Entity_Id; E : Entity_Id) is
      begin
         Error_Msg_Sloc := Sloc (E);

         --  Generate message, with useful additional warning if in generic

         if Is_Generic_Unit (E) then
            Error_Msg_N ("previous generic unit cannot be overloaded", S);
            Error_Msg_N ("\& conflicts with declaration#", S);
         else
            Error_Msg_N ("& conflicts with declaration#", S);
         end if;
      end Report_Conflict;

   --  Start of processing for New_Overloaded_Entity

   begin
      --  We need to look for an entity that S may override. This must be a
      --  homonym in the current scope, so we look for the first homonym of
      --  S in the current scope as the starting point for the search.

      E := Current_Entity_In_Scope (S);

      --  Ada 2005 (AI-251): Derivation of abstract interface primitives.
      --  They are directly added to the list of primitive operations of
      --  Derived_Type, unless this is a rederivation in the private part
      --  of an operation that was already derived in the visible part of
      --  the current package.

      if Ada_Version >= Ada_2005
        and then Present (Derived_Type)
        and then Present (Alias (S))
        and then Is_Dispatching_Operation (Alias (S))
        and then Present (Find_Dispatching_Type (Alias (S)))
        and then Is_Interface (Find_Dispatching_Type (Alias (S)))
      then
         --  For private types, when the full-view is processed we propagate to
         --  the full view the non-overridden entities whose attribute "alias"
         --  references an interface primitive. These entities were added by
         --  Derive_Subprograms to ensure that interface primitives are
         --  covered.

         --  Inside_Freeze_Actions is non zero when S corresponds with an
         --  internal entity that links an interface primitive with its
         --  covering primitive through attribute Interface_Alias (see
         --  Add_Internal_Interface_Entities).

         if Inside_Freezing_Actions = 0
           and then Is_Package_Or_Generic_Package (Current_Scope)
           and then In_Private_Part (Current_Scope)
           and then Nkind (Parent (E)) = N_Private_Extension_Declaration
           and then Nkind (Parent (S)) = N_Full_Type_Declaration
           and then Full_View (Defining_Identifier (Parent (E)))
                      = Defining_Identifier (Parent (S))
           and then Alias (E) = Alias (S)
         then
            Check_Operation_From_Private_View (S, E);
            Set_Is_Dispatching_Operation (S);

         --  Common case

         else
            Enter_Overloaded_Entity (S);
            Check_Dispatching_Operation (S, Empty);
            Check_For_Primitive_Subprogram (Is_Primitive_Subp);
         end if;

         return;
      end if;

      --  For synchronized types check conflicts of this entity with previously
      --  defined entities.

      if Ada_Version >= Ada_2005
        and then Has_Matching_Entry_Or_Subprogram (S)
      then
         return;
      end if;

      --  If there is no homonym then this is definitely not overriding

      if No (E) then
         Enter_Overloaded_Entity (S);
         Check_Dispatching_Operation (S, Empty);
         Check_For_Primitive_Subprogram (Is_Primitive_Subp);

         --  If subprogram has an explicit declaration, check whether it has an
         --  overriding indicator.

         if Comes_From_Source (S) then
            Check_Synchronized_Overriding (S, Overridden_Subp);

            --  (Ada 2012: AI05-0125-1): If S is a dispatching operation then
            --  it may have overridden some hidden inherited primitive. Update
            --  Overridden_Subp to avoid spurious errors when checking the
            --  overriding indicator.

            if Ada_Version >= Ada_2012
              and then No (Overridden_Subp)
              and then Is_Dispatching_Operation (S)
              and then Present (Overridden_Operation (S))
            then
               Overridden_Subp := Overridden_Operation (S);
            end if;

            Check_Overriding_Indicator
              (S, Overridden_Subp, Is_Primitive => Is_Primitive_Subp);

            --  The Ghost policy in effect at the point of declaration of a
            --  parent subprogram and an overriding subprogram must match
            --  (SPARK RM 6.9(17)).

            Check_Ghost_Overriding (S, Overridden_Subp);
         end if;

      --  If there is a homonym that is not overloadable, then we have an
      --  error, except for the special cases checked explicitly below.

      elsif not Is_Overloadable (E) then

         --  Check for spurious conflict produced by a subprogram that has the
         --  same name as that of the enclosing generic package. The conflict
         --  occurs within an instance, between the subprogram and the renaming
         --  declaration for the package. After the subprogram, the package
         --  renaming declaration becomes hidden.

         if Ekind (E) = E_Package
           and then Present (Renamed_Object (E))
           and then Renamed_Object (E) = Current_Scope
           and then Nkind (Parent (Renamed_Object (E))) =
                                                     N_Package_Specification
           and then Present (Generic_Parent (Parent (Renamed_Object (E))))
         then
            Set_Is_Hidden (E);
            Set_Is_Immediately_Visible (E, False);
            Enter_Overloaded_Entity (S);
            Set_Homonym (S, Homonym (E));
            Check_Dispatching_Operation (S, Empty);
            Check_Overriding_Indicator (S, Empty, Is_Primitive => False);

         --  If the subprogram is implicit it is hidden by the previous
         --  declaration. However if it is dispatching, it must appear in the
         --  dispatch table anyway, because it can be dispatched to even if it
         --  cannot be called directly.

         elsif Present (Alias (S)) and then not Comes_From_Source (S) then
            Set_Scope (S, Current_Scope);

            if Is_Dispatching_Operation (Alias (S)) then
               Check_Dispatching_Operation (S, Empty);
            end if;

            return;

         else
            Report_Conflict (S, E);
            return;
         end if;

      --  E exists and is overloadable

      else
         Check_Synchronized_Overriding (S, Overridden_Subp);

         --  Loop through E and its homonyms to determine if any of them is
         --  the candidate for overriding by S.

         while Present (E) loop

            --  Definitely not interesting if not in the current scope

            if Scope (E) /= Current_Scope then
               null;

            --  A function can overload the name of an abstract state. The
            --  state can be viewed as a function with a profile that cannot
            --  be matched by anything.

            elsif Ekind (S) = E_Function
              and then Ekind (E) = E_Abstract_State
            then
               Enter_Overloaded_Entity (S);
               return;

            --  Ada 2012 (AI05-0165): For internally generated bodies of null
            --  procedures locate the internally generated spec. We enforce
            --  mode conformance since a tagged type may inherit from
            --  interfaces several null primitives which differ only in
            --  the mode of the formals.

            elsif not Comes_From_Source (S)
              and then Is_Null_Procedure (S)
              and then not Mode_Conformant (E, S)
            then
               null;

            --  Check if we have type conformance

            elsif Type_Conformant (E, S) then

               --  If the old and new entities have the same profile and one
               --  is not the body of the other, then this is an error, unless
               --  one of them is implicitly declared.

               --  There are some cases when both can be implicit, for example
               --  when both a literal and a function that overrides it are
               --  inherited in a derivation, or when an inherited operation
               --  of a tagged full type overrides the inherited operation of
               --  a private extension. Ada 83 had a special rule for the
               --  literal case. In Ada 95, the later implicit operation hides
               --  the former, and the literal is always the former. In the
               --  odd case where both are derived operations declared at the
               --  same point, both operations should be declared, and in that
               --  case we bypass the following test and proceed to the next
               --  part. This can only occur for certain obscure cases in
               --  instances, when an operation on a type derived from a formal
               --  private type does not override a homograph inherited from
               --  the actual. In subsequent derivations of such a type, the
               --  DT positions of these operations remain distinct, if they
               --  have been set.

               if Present (Alias (S))
                 and then (No (Alias (E))
                            or else Comes_From_Source (E)
                            or else Is_Abstract_Subprogram (S)
                            or else
                              (Is_Dispatching_Operation (E)
                                and then Is_Overriding_Alias (E, S)))
                 and then Ekind (E) /= E_Enumeration_Literal
               then
                  --  When an derived operation is overloaded it may be due to
                  --  the fact that the full view of a private extension
                  --  re-inherits. It has to be dealt with.

                  if Is_Package_Or_Generic_Package (Current_Scope)
                    and then In_Private_Part (Current_Scope)
                  then
                     Check_Operation_From_Private_View (S, E);
                  end if;

                  --  In any case the implicit operation remains hidden by the
                  --  existing declaration, which is overriding. Indicate that
                  --  E overrides the operation from which S is inherited.

                  if Present (Alias (S)) then
                     Set_Overridden_Operation    (E, Alias (S));
                     Inherit_Subprogram_Contract (E, Alias (S));

                  else
                     Set_Overridden_Operation    (E, S);
                     Inherit_Subprogram_Contract (E, S);
                  end if;

                  --  When a dispatching operation overrides an inherited
                  --  subprogram, it shall be subtype conformant with the
                  --  inherited subprogram (RM 3.9.2 (10.2)).

                  if Comes_From_Source (E)
                    and then Is_Dispatching_Operation (E)
                    and then Find_Dispatching_Type (S)
                               = Find_Dispatching_Type (E)
                  then
                     Check_Subtype_Conformant (E, S);
                  end if;

                  if Comes_From_Source (E) then
                     Check_Overriding_Indicator (E, S, Is_Primitive => False);

                     --  The Ghost policy in effect at the point of declaration
                     --  of a parent subprogram and an overriding subprogram
                     --  must match (SPARK RM 6.9(17)).

                     Check_Ghost_Overriding (E, S);
                  end if;

                  return;

               --  Within an instance, the renaming declarations for actual
               --  subprograms may become ambiguous, but they do not hide each
               --  other.

               elsif Ekind (E) /= E_Entry
                 and then not Comes_From_Source (E)
                 and then not Is_Generic_Instance (E)
                 and then (Present (Alias (E))
                            or else Is_Intrinsic_Subprogram (E))
                 and then (not In_Instance
                            or else No (Parent (E))
                            or else Nkind (Unit_Declaration_Node (E)) /=
                                      N_Subprogram_Renaming_Declaration)
               then
                  --  A subprogram child unit is not allowed to override an
                  --  inherited subprogram (10.1.1(20)).

                  if Is_Child_Unit (S) then
                     Error_Msg_N
                       ("child unit overrides inherited subprogram in parent",
                        S);
                     return;
                  end if;

                  if Is_Non_Overriding_Operation (E, S) then
                     Enter_Overloaded_Entity (S);

                     if No (Derived_Type)
                       or else Is_Tagged_Type (Derived_Type)
                     then
                        Check_Dispatching_Operation (S, Empty);
                     end if;

                     return;
                  end if;

                  --  E is a derived operation or an internal operator which
                  --  is being overridden. Remove E from further visibility.
                  --  Furthermore, if E is a dispatching operation, it must be
                  --  replaced in the list of primitive operations of its type
                  --  (see Override_Dispatching_Operation).

                  Overridden_Subp := E;

                  --  It is possible for E to be in the current scope and
                  --  yet not in the entity chain. This can only occur in a
                  --  generic context where E is an implicit concatenation
                  --  in the formal part, because in a generic body the
                  --  entity chain starts with the formals.

                  --  In GNATprove mode, a wrapper for an operation with
                  --  axiomatization may be a homonym of another declaration
                  --  for an actual subprogram (needs refinement ???).

                  if No (Prev_Entity (E)) then
                     if In_Instance
                       and then GNATprove_Mode
                       and then
                         Nkind (Original_Node (Unit_Declaration_Node (S))) =
                                          N_Subprogram_Renaming_Declaration
                     then
                        return;
                     else
                        pragma Assert (Chars (E) = Name_Op_Concat);
                        null;
                     end if;
                  end if;

                  --  E must be removed both from the entity_list of the
                  --  current scope, and from the visibility chain.

                  if Debug_Flag_E then
                     Write_Str ("Override implicit operation ");
                     Write_Int (Int (E));
                     Write_Eol;
                  end if;

                  --  If E is a predefined concatenation, it stands for four
                  --  different operations. As a result, a single explicit
                  --  declaration does not hide it. In a possible ambiguous
                  --  situation, Disambiguate chooses the user-defined op,
                  --  so it is correct to retain the previous internal one.

                  if Chars (E) /= Name_Op_Concat
                    or else Ekind (E) /= E_Operator
                  then
                     --  For nondispatching derived operations that are
                     --  overridden by a subprogram declared in the private
                     --  part of a package, we retain the derived subprogram
                     --  but mark it as not immediately visible. If the
                     --  derived operation was declared in the visible part
                     --  then this ensures that it will still be visible
                     --  outside the package with the proper signature
                     --  (calls from outside must also be directed to this
                     --  version rather than the overriding one, unlike the
                     --  dispatching case). Calls from inside the package
                     --  will still resolve to the overriding subprogram
                     --  since the derived one is marked as not visible
                     --  within the package.

                     --  If the private operation is dispatching, we achieve
                     --  the overriding by keeping the implicit operation
                     --  but setting its alias to be the overriding one. In
                     --  this fashion the proper body is executed in all
                     --  cases, but the original signature is used outside
                     --  of the package.

                     --  If the overriding is not in the private part, we
                     --  remove the implicit operation altogether.

                     if Is_Private_Declaration (S) then
                        if not Is_Dispatching_Operation (E) then
                           Set_Is_Immediately_Visible (E, False);
                        else
                           --  Work done in Override_Dispatching_Operation, so
                           --  nothing else needs to be done here.

                           null;
                        end if;

                     else
                        Remove_Entity_And_Homonym (E);
                     end if;
                  end if;

                  Enter_Overloaded_Entity (S);

                  --  For entities generated by Derive_Subprograms the
                  --  overridden operation is the inherited primitive
                  --  (which is available through the attribute alias).

                  if not (Comes_From_Source (E))
                    and then Is_Dispatching_Operation (E)
                    and then Find_Dispatching_Type (E) =
                             Find_Dispatching_Type (S)
                    and then Present (Alias (E))
                    and then Comes_From_Source (Alias (E))
                  then
                     Set_Overridden_Operation    (S, Alias (E));
                     Inherit_Subprogram_Contract (S, Alias (E));

                  --  Normal case of setting entity as overridden

                  --  Note: Static_Initialization and Overridden_Operation
                  --  attributes use the same field in subprogram entities.
                  --  Static_Initialization is only defined for internal
                  --  initialization procedures, where Overridden_Operation
                  --  is irrelevant. Therefore the setting of this attribute
                  --  must check whether the target is an init_proc.

                  elsif not Is_Init_Proc (S) then
                     Set_Overridden_Operation    (S, E);
                     Inherit_Subprogram_Contract (S, E);
                  end if;

                  Check_Overriding_Indicator (S, E, Is_Primitive => True);

                  --  The Ghost policy in effect at the point of declaration
                  --  of a parent subprogram and an overriding subprogram
                  --  must match (SPARK RM 6.9(17)).

                  Check_Ghost_Overriding (S, E);

                  --  If S is a user-defined subprogram or a null procedure
                  --  expanded to override an inherited null procedure, or a
                  --  predefined dispatching primitive then indicate that E
                  --  overrides the operation from which S is inherited.

                  if Comes_From_Source (S)
                    or else
                      (Present (Parent (S))
                        and then Nkind (Parent (S)) = N_Procedure_Specification
                        and then Null_Present (Parent (S)))
                    or else
                      (Present (Alias (E))
                        and then
                          Is_Predefined_Dispatching_Operation (Alias (E)))
                  then
                     if Present (Alias (E)) then
                        Set_Overridden_Operation    (S, Alias (E));
                        Inherit_Subprogram_Contract (S, Alias (E));
                     end if;
                  end if;

                  if Is_Dispatching_Operation (E) then

                     --  An overriding dispatching subprogram inherits the
                     --  convention of the overridden subprogram (AI-117).

                     Set_Convention (S, Convention (E));
                     Check_Dispatching_Operation (S, E);

                  else
                     Check_Dispatching_Operation (S, Empty);
                  end if;

                  Check_For_Primitive_Subprogram
                    (Is_Primitive_Subp, Is_Overriding => True);
                  goto Check_Inequality;

               --  Apparent redeclarations in instances can occur when two
               --  formal types get the same actual type. The subprograms in
               --  in the instance are legal,  even if not callable from the
               --  outside. Calls from within are disambiguated elsewhere.
               --  For dispatching operations in the visible part, the usual
               --  rules apply, and operations with the same profile are not
               --  legal (B830001).

               elsif (In_Instance_Visible_Part
                       and then not Is_Dispatching_Operation (E))
                 or else In_Instance_Not_Visible
               then
                  null;

               --  Here we have a real error (identical profile)

               else
                  Error_Msg_Sloc := Sloc (E);

                  --  Avoid cascaded errors if the entity appears in
                  --  subsequent calls.

                  Set_Scope (S, Current_Scope);

                  --  Generate error, with extra useful warning for the case
                  --  of a generic instance with no completion.

                  if Is_Generic_Instance (S)
                    and then not Has_Completion (E)
                  then
                     Error_Msg_N
                       ("instantiation cannot provide body for&", S);
                     Error_Msg_N ("\& conflicts with declaration#", S);
                  else
                     Error_Msg_N ("& conflicts with declaration#", S);
                  end if;

                  return;
               end if;

            else
               --  If one subprogram has an access parameter and the other
               --  a parameter of an access type, calls to either might be
               --  ambiguous. Verify that parameters match except for the
               --  access parameter.

               if May_Hide_Profile then
                  declare
                     F1 : Entity_Id;
                     F2 : Entity_Id;

                  begin
                     F1 := First_Formal (S);
                     F2 := First_Formal (E);
                     while Present (F1) and then Present (F2) loop
                        if Is_Access_Type (Etype (F1)) then
                           if not Is_Access_Type (Etype (F2))
                              or else not Conforming_Types
                                (Designated_Type (Etype (F1)),
                                 Designated_Type (Etype (F2)),
                                 Type_Conformant)
                           then
                              May_Hide_Profile := False;
                           end if;

                        elsif
                          not Conforming_Types
                            (Etype (F1), Etype (F2), Type_Conformant)
                        then
                           May_Hide_Profile := False;
                        end if;

                        Next_Formal (F1);
                        Next_Formal (F2);
                     end loop;

                     if May_Hide_Profile
                       and then No (F1)
                       and then No (F2)
                     then
                        Error_Msg_NE ("calls to& may be ambiguous??", S, S);
                     end if;
                  end;
               end if;
            end if;

            E := Homonym (E);
         end loop;

         --  On exit, we know that S is a new entity

         Enter_Overloaded_Entity (S);
         Check_For_Primitive_Subprogram (Is_Primitive_Subp);
         Check_Overriding_Indicator
           (S, Overridden_Subp, Is_Primitive => Is_Primitive_Subp);

         --  The Ghost policy in effect at the point of declaration of a parent
         --  subprogram and an overriding subprogram must match
         --  (SPARK RM 6.9(17)).

         Check_Ghost_Overriding (S, Overridden_Subp);

         --  If S is a derived operation for an untagged type then by
         --  definition it's not a dispatching operation (even if the parent
         --  operation was dispatching), so Check_Dispatching_Operation is not
         --  called in that case.

         if No (Derived_Type)
           or else Is_Tagged_Type (Derived_Type)
         then
            Check_Dispatching_Operation (S, Empty);
         end if;
      end if;

      --  If this is a user-defined equality operator that is not a derived
      --  subprogram, create the corresponding inequality. If the operation is
      --  dispatching, the expansion is done elsewhere, and we do not create
      --  an explicit inequality operation.

      <<Check_Inequality>>
         if Chars (S) = Name_Op_Eq
           and then Etype (S) = Standard_Boolean
           and then Present (Parent (S))
           and then not Is_Dispatching_Operation (S)
         then
            Make_Inequality_Operator (S);
            Check_Untagged_Equality (S);
         end if;
   end New_Overloaded_Entity;

   ----------------------------------
   -- Preanalyze_Formal_Expression --
   ----------------------------------

   procedure Preanalyze_Formal_Expression (N : Node_Id; T : Entity_Id) is
      Save_In_Spec_Expression : constant Boolean := In_Spec_Expression;
   begin
      In_Spec_Expression := True;
      Preanalyze_With_Freezing_And_Resolve (N, T);
      In_Spec_Expression := Save_In_Spec_Expression;
   end Preanalyze_Formal_Expression;

   ---------------------
   -- Process_Formals --
   ---------------------

   procedure Process_Formals
     (T           : List_Id;
      Related_Nod : Node_Id)
   is
      function Designates_From_Limited_With (Typ : Entity_Id) return Boolean;
      --  Determine whether an access type designates a type coming from a
      --  limited view.

      function Is_Class_Wide_Default (D : Node_Id) return Boolean;
      --  Check whether the default has a class-wide type. After analysis the
      --  default has the type of the formal, so we must also check explicitly
      --  for an access attribute.

      ----------------------------------
      -- Designates_From_Limited_With --
      ----------------------------------

      function Designates_From_Limited_With (Typ : Entity_Id) return Boolean is
         Desig : Entity_Id := Typ;

      begin
         if Is_Access_Type (Desig) then
            Desig := Directly_Designated_Type (Desig);
         end if;

         if Is_Class_Wide_Type (Desig) then
            Desig := Root_Type (Desig);
         end if;

         return
           Ekind (Desig) = E_Incomplete_Type
             and then From_Limited_With (Desig);
      end Designates_From_Limited_With;

      ---------------------------
      -- Is_Class_Wide_Default --
      ---------------------------

      function Is_Class_Wide_Default (D : Node_Id) return Boolean is
      begin
         return Is_Class_Wide_Type (Designated_Type (Etype (D)))
           or else (Nkind (D) = N_Attribute_Reference
                     and then Attribute_Name (D) = Name_Access
                     and then Is_Class_Wide_Type (Etype (Prefix (D))));
      end Is_Class_Wide_Default;

      --  Local variables

      Context     : constant Node_Id := Parent (Parent (T));
      Default     : Node_Id;
      Formal      : Entity_Id;
      Formal_Type : Entity_Id;
      Param_Spec  : Node_Id;
      Ptype       : Entity_Id;

      Num_Out_Params  : Nat       := 0;
      First_Out_Param : Entity_Id := Empty;
      --  Used for setting Is_Only_Out_Parameter

   --  Start of processing for Process_Formals

   begin
      --  In order to prevent premature use of the formals in the same formal
      --  part, the Ekind is left undefined until all default expressions are
      --  analyzed. The Ekind is established in a separate loop at the end.

      Param_Spec := First (T);
      while Present (Param_Spec) loop
         Formal := Defining_Identifier (Param_Spec);
         Set_Never_Set_In_Source (Formal, True);
         Enter_Name (Formal);

         --  Case of ordinary parameters

         if Nkind (Parameter_Type (Param_Spec)) /= N_Access_Definition then
            Find_Type (Parameter_Type (Param_Spec));
            Ptype := Parameter_Type (Param_Spec);

            if Ptype = Error then
               goto Continue;
            end if;

            --  Protect against malformed parameter types

            if Nkind (Ptype) not in N_Has_Entity then
               Formal_Type := Any_Type;
            else
               Formal_Type := Entity (Ptype);
            end if;

            if Is_Incomplete_Type (Formal_Type)
              or else
               (Is_Class_Wide_Type (Formal_Type)
                 and then Is_Incomplete_Type (Root_Type (Formal_Type)))
            then
               --  Ada 2005 (AI-326): Tagged incomplete types allowed in
               --  primitive operations, as long as their completion is
               --  in the same declarative part. If in the private part
               --  this means that the type cannot be a Taft-amendment type.
               --  Check is done on package exit. For access to subprograms,
               --  the use is legal for Taft-amendment types.

               --  Ada 2012: tagged incomplete types are allowed as generic
               --  formal types. They do not introduce dependencies and the
               --  corresponding generic subprogram does not have a delayed
               --  freeze, because it does not need a freeze node. However,
               --  it is still the case that untagged incomplete types cannot
               --  be Taft-amendment types and must be completed in private
               --  part, so the subprogram must appear in the list of private
               --  dependents of the type.

               if Is_Tagged_Type (Formal_Type)
                 or else (Ada_Version >= Ada_2012
                           and then not From_Limited_With (Formal_Type)
                           and then not Is_Generic_Type (Formal_Type))
               then
                  if Ekind (Scope (Current_Scope)) = E_Package
                    and then not Is_Generic_Type (Formal_Type)
                    and then not Is_Class_Wide_Type (Formal_Type)
                  then
                     if Nkind (Parent (T)) not in
                          N_Access_Function_Definition |
                          N_Access_Procedure_Definition
                     then
                        Append_Elmt (Current_Scope,
                          Private_Dependents (Base_Type (Formal_Type)));

                        --  Freezing is delayed to ensure that Register_Prim
                        --  will get called for this operation, which is needed
                        --  in cases where static dispatch tables aren't built.
                        --  (Note that the same is done for controlling access
                        --  parameter cases in function Access_Definition.)

                        if not Is_Thunk (Current_Scope) then
                           Set_Has_Delayed_Freeze (Current_Scope);
                        end if;
                     end if;
                  end if;

               elsif Nkind (Parent (T)) not in N_Access_Function_Definition
                                             | N_Access_Procedure_Definition
               then
                  --  AI05-0151: Tagged incomplete types are allowed in all
                  --  formal parts. Untagged incomplete types are not allowed
                  --  in bodies. Limited views of either kind are not allowed
                  --  if there is no place at which the non-limited view can
                  --  become available.

                  --  Incomplete formal untagged types are not allowed in
                  --  subprogram bodies (but are legal in their declarations).
                  --  This excludes bodies created for null procedures, which
                  --  are basic declarations.

                  if Is_Generic_Type (Formal_Type)
                    and then not Is_Tagged_Type (Formal_Type)
                    and then Nkind (Parent (Related_Nod)) = N_Subprogram_Body
                  then
                     Error_Msg_N
                       ("invalid use of formal incomplete type", Param_Spec);

                  elsif Ada_Version >= Ada_2012 then
                     if Is_Tagged_Type (Formal_Type)
                       and then (not From_Limited_With (Formal_Type)
                                  or else not In_Package_Body)
                     then
                        null;

                     elsif Nkind (Context) in N_Accept_Statement
                                            | N_Accept_Alternative
                                            | N_Entry_Body
                       or else (Nkind (Context) = N_Subprogram_Body
                                 and then Comes_From_Source (Context))
                     then
                        Error_Msg_NE
                          ("invalid use of untagged incomplete type &",
                           Ptype, Formal_Type);
                     end if;

                  else
                     Error_Msg_NE
                       ("invalid use of incomplete type&",
                        Param_Spec, Formal_Type);

                     --  Further checks on the legality of incomplete types
                     --  in formal parts are delayed until the freeze point
                     --  of the enclosing subprogram or access to subprogram.
                  end if;
               end if;

            elsif Ekind (Formal_Type) = E_Void then
               Error_Msg_NE
                 ("premature use of&",
                  Parameter_Type (Param_Spec), Formal_Type);
            end if;

            --  Ada 2012 (AI-142): Handle aliased parameters

            if Ada_Version >= Ada_2012
              and then Aliased_Present (Param_Spec)
            then
               Set_Is_Aliased (Formal);

               --  AI12-001: All aliased objects are considered to be specified
               --  as independently addressable (RM C.6(8.1/4)).

               Set_Is_Independent (Formal);
            end if;

            --  Ada 2005 (AI-231): Create and decorate an internal subtype
            --  declaration corresponding to the null-excluding type of the
            --  formal in the enclosing scope. Finally, replace the parameter
            --  type of the formal with the internal subtype.

            if Ada_Version >= Ada_2005
              and then Null_Exclusion_Present (Param_Spec)
            then
               if not Is_Access_Type (Formal_Type) then
                  Error_Msg_N
                    ("`NOT NULL` allowed only for an access type", Param_Spec);

               else
                  if Can_Never_Be_Null (Formal_Type)
                    and then Comes_From_Source (Related_Nod)
                  then
                     Error_Msg_NE
                       ("`NOT NULL` not allowed (& already excludes null)",
                        Param_Spec, Formal_Type);
                  end if;

                  Formal_Type :=
                    Create_Null_Excluding_Itype
                      (T           => Formal_Type,
                       Related_Nod => Related_Nod,
                       Scope_Id    => Scope (Current_Scope));

                  --  If the designated type of the itype is an itype that is
                  --  not frozen yet, we set the Has_Delayed_Freeze attribute
                  --  on the access subtype, to prevent order-of-elaboration
                  --  issues in the backend.

                  --  Example:
                  --     type T is access procedure;
                  --     procedure Op (O : not null T);

                  if Is_Itype (Directly_Designated_Type (Formal_Type))
                    and then
                      not Is_Frozen (Directly_Designated_Type (Formal_Type))
                  then
                     Set_Has_Delayed_Freeze (Formal_Type);
                  end if;
               end if;
            end if;

         --  An access formal type

         else
            Formal_Type :=
              Access_Definition (Related_Nod, Parameter_Type (Param_Spec));

            --  No need to continue if we already notified errors

            if not Present (Formal_Type) then
               return;
            end if;

            --  Ada 2005 (AI-254)

            declare
               AD : constant Node_Id :=
                      Access_To_Subprogram_Definition
                        (Parameter_Type (Param_Spec));
            begin
               if Present (AD) and then Protected_Present (AD) then
                  Formal_Type :=
                    Replace_Anonymous_Access_To_Protected_Subprogram
                      (Param_Spec);
               end if;
            end;
         end if;

         Set_Etype (Formal, Formal_Type);

         --  Deal with default expression if present

         Default := Expression (Param_Spec);

         if Present (Default) then
            if Out_Present (Param_Spec) then
               Error_Msg_N
                 ("default initialization only allowed for IN parameters",
                  Param_Spec);
            end if;

            --  Do the special preanalysis of the expression (see section on
            --  "Handling of Default Expressions" in the spec of package Sem).

            Preanalyze_Formal_Expression (Default, Formal_Type);

            --  An access to constant cannot be the default for
            --  an access parameter that is an access to variable.

            if Ekind (Formal_Type) = E_Anonymous_Access_Type
              and then not Is_Access_Constant (Formal_Type)
              and then Is_Access_Type (Etype (Default))
              and then Is_Access_Constant (Etype (Default))
            then
               Error_Msg_N
                 ("formal that is access to variable cannot be initialized "
                  & "with an access-to-constant expression", Default);
            end if;

            --  Check that the designated type of an access parameter's default
            --  is not a class-wide type unless the parameter's designated type
            --  is also class-wide.

            if Ekind (Formal_Type) = E_Anonymous_Access_Type
              and then not Designates_From_Limited_With (Formal_Type)
              and then Is_Class_Wide_Default (Default)
              and then not Is_Class_Wide_Type (Designated_Type (Formal_Type))
            then
               Error_Msg_N
                 ("access to class-wide expression not allowed here", Default);
            end if;

            --  Check incorrect use of dynamically tagged expressions

            if Is_Tagged_Type (Formal_Type) then
               Check_Dynamically_Tagged_Expression
                 (Expr        => Default,
                  Typ         => Formal_Type,
                  Related_Nod => Default);
            end if;
         end if;

         --  Ada 2005 (AI-231): Static checks

         if Ada_Version >= Ada_2005
           and then Is_Access_Type (Etype (Formal))
           and then Can_Never_Be_Null (Etype (Formal))
         then
            Null_Exclusion_Static_Checks (Param_Spec);
         end if;

         --  The following checks are relevant only when SPARK_Mode is on as
         --  these are not standard Ada legality rules.

         if SPARK_Mode = On then
            if Ekind (Scope (Formal)) in E_Function | E_Generic_Function then

               --  A function cannot have a parameter of mode IN OUT or OUT
               --  (SPARK RM 6.1).

               if Ekind (Formal) in E_In_Out_Parameter | E_Out_Parameter then
                  Error_Msg_N
                    ("function cannot have parameter of mode `OUT` or "
                     & "`IN OUT`", Formal);
               end if;

            --  A procedure cannot have an effectively volatile formal
            --  parameter of mode IN because it behaves as a constant
            --  (SPARK RM 7.1.3(4)).

            elsif Ekind (Scope (Formal)) = E_Procedure
              and then Ekind (Formal) = E_In_Parameter
              and then Is_Effectively_Volatile (Formal)
            then
               Error_Msg_N
                 ("formal parameter of mode `IN` cannot be volatile", Formal);
            end if;
         end if;

         --  Deal with aspects on formal parameters. Only Unreferenced is
         --  supported for the time being.

         if Has_Aspects (Param_Spec) then
            declare
               Aspect : Node_Id := First (Aspect_Specifications (Param_Spec));
            begin
               while Present (Aspect) loop
                  if Chars (Identifier (Aspect)) = Name_Unreferenced then
                     Set_Has_Pragma_Unreferenced (Formal);
                  else
                     Error_Msg_NE
                       ("unsupported aspect& on parameter",
                        Aspect, Identifier (Aspect));
                  end if;

                  Next (Aspect);
               end loop;
            end;
         end if;

      <<Continue>>
         Next (Param_Spec);
      end loop;

      --  If this is the formal part of a function specification, analyze the
      --  subtype mark in the context where the formals are visible but not
      --  yet usable, and may hide outer homographs.

      if Nkind (Related_Nod) = N_Function_Specification then
         Analyze_Return_Type (Related_Nod);
      end if;

      --  Now set the kind (mode) of each formal

      Param_Spec := First (T);
      while Present (Param_Spec) loop
         Formal := Defining_Identifier (Param_Spec);
         Set_Formal_Mode (Formal);

         if Ekind (Formal) = E_In_Parameter then
            Set_Default_Value (Formal, Expression (Param_Spec));

            if Present (Expression (Param_Spec)) then
               Default := Expression (Param_Spec);

               if Is_Scalar_Type (Etype (Default)) then
                  if Nkind (Parameter_Type (Param_Spec)) /=
                                              N_Access_Definition
                  then
                     Formal_Type := Entity (Parameter_Type (Param_Spec));
                  else
                     Formal_Type :=
                       Access_Definition
                         (Related_Nod, Parameter_Type (Param_Spec));
                  end if;

                  Apply_Scalar_Range_Check (Default, Formal_Type);
               end if;
            end if;

         elsif Ekind (Formal) = E_Out_Parameter then
            Num_Out_Params := Num_Out_Params + 1;

            if Num_Out_Params = 1 then
               First_Out_Param := Formal;
            end if;

         elsif Ekind (Formal) = E_In_Out_Parameter then
            Num_Out_Params := Num_Out_Params + 1;
         end if;

         --  Skip remaining processing if formal type was in error

         if Etype (Formal) = Any_Type or else Error_Posted (Formal) then
            goto Next_Parameter;
         end if;

         --  Force call by reference if aliased

         declare
            Conv : constant Convention_Id := Convention (Etype (Formal));
         begin
            if Is_Aliased (Formal) then
               Set_Mechanism (Formal, By_Reference);

               --  Warn if user asked this to be passed by copy

               if Conv = Convention_Ada_Pass_By_Copy then
                  Error_Msg_N
                    ("cannot pass aliased parameter & by copy??", Formal);
               end if;

            --  Force mechanism if type has Convention Ada_Pass_By_Ref/Copy

            elsif Conv = Convention_Ada_Pass_By_Copy then
               Set_Mechanism (Formal, By_Copy);

            elsif Conv = Convention_Ada_Pass_By_Reference then
               Set_Mechanism (Formal, By_Reference);
            end if;
         end;

      <<Next_Parameter>>
         Next (Param_Spec);
      end loop;

      if Present (First_Out_Param) and then Num_Out_Params = 1 then
         Set_Is_Only_Out_Parameter (First_Out_Param);
      end if;
   end Process_Formals;

   ----------------------------
   -- Reference_Body_Formals --
   ----------------------------

   procedure Reference_Body_Formals (Spec : Entity_Id; Bod : Entity_Id) is
      Fs : Entity_Id;
      Fb : Entity_Id;

   begin
      if Error_Posted (Spec) then
         return;
      end if;

      --  Iterate over both lists. They may be of different lengths if the two
      --  specs are not conformant.

      Fs := First_Formal (Spec);
      Fb := First_Formal (Bod);
      while Present (Fs) and then Present (Fb) loop
         Generate_Reference (Fs, Fb, 'b');

         if Style_Check then
            Style.Check_Identifier (Fb, Fs);
         end if;

         Set_Spec_Entity (Fb, Fs);
         Set_Referenced (Fs, False);
         Next_Formal (Fs);
         Next_Formal (Fb);
      end loop;
   end Reference_Body_Formals;

   -------------------------
   -- Set_Actual_Subtypes --
   -------------------------

   procedure Set_Actual_Subtypes (N : Node_Id; Subp : Entity_Id) is
      Decl       : Node_Id;
      Formal     : Entity_Id;
      T          : Entity_Id;
      First_Stmt : Node_Id := Empty;
      AS_Needed  : Boolean;

   begin
      --  If this is an empty initialization procedure, no need to create
      --  actual subtypes (small optimization).

      if Ekind (Subp) = E_Procedure and then Is_Null_Init_Proc (Subp) then
         return;

      --  Within a predicate function we do not want to generate local
      --  subtypes that may generate nested predicate functions.

      elsif Is_Subprogram (Subp) and then Is_Predicate_Function (Subp) then
         return;
      end if;

      --  The subtype declarations may freeze the formals. The body generated
      --  for an expression function is not a freeze point, so do not emit
      --  these declarations (small loss of efficiency in rare cases).

      if Nkind (N) = N_Subprogram_Body
        and then Was_Expression_Function (N)
      then
         return;
      end if;

      Formal := First_Formal (Subp);
      while Present (Formal) loop
         T := Etype (Formal);

         --  We never need an actual subtype for a constrained formal

         if Is_Constrained (T) then
            AS_Needed := False;

         --  If we have unknown discriminants, then we do not need an actual
         --  subtype, or more accurately we cannot figure it out. Note that
         --  all class-wide types have unknown discriminants.

         elsif Has_Unknown_Discriminants (T) then
            AS_Needed := False;

         --  At this stage we have an unconstrained type that may need an
         --  actual subtype. For sure the actual subtype is needed if we have
         --  an unconstrained array type. However, in an instance, the type
         --  may appear as a subtype of the full view, while the actual is
         --  in fact private (in which case no actual subtype is needed) so
         --  check the kind of the base type.

         elsif Is_Array_Type (Base_Type (T)) then
            AS_Needed := True;

         --  The only other case needing an actual subtype is an unconstrained
         --  record type which is an IN parameter (we cannot generate actual
         --  subtypes for the OUT or IN OUT case, since an assignment can
         --  change the discriminant values. However we exclude the case of
         --  initialization procedures, since discriminants are handled very
         --  specially in this context, see the section entitled "Handling of
         --  Discriminants" in Einfo.

         --  We also exclude the case of Discrim_SO_Functions (functions used
         --  in front-end layout mode for size/offset values), since in such
         --  functions only discriminants are referenced, and not only are such
         --  subtypes not needed, but they cannot always be generated, because
         --  of order of elaboration issues.

         elsif Is_Record_Type (T)
           and then Ekind (Formal) = E_In_Parameter
           and then Chars (Formal) /= Name_uInit
           and then not Is_Unchecked_Union (T)
           and then not Is_Discrim_SO_Function (Subp)
         then
            AS_Needed := True;

         --  All other cases do not need an actual subtype

         else
            AS_Needed := False;
         end if;

         --  Generate actual subtypes for unconstrained arrays and
         --  unconstrained discriminated records.

         if AS_Needed then
            if Nkind (N) = N_Accept_Statement then

               --  If expansion is active, the formal is replaced by a local
               --  variable that renames the corresponding entry of the
               --  parameter block, and it is this local variable that may
               --  require an actual subtype.

               if Expander_Active then
                  Decl := Build_Actual_Subtype (T, Renamed_Object (Formal));
               else
                  Decl := Build_Actual_Subtype (T, Formal);
               end if;

               if Present (Handled_Statement_Sequence (N)) then
                  First_Stmt :=
                    First (Statements (Handled_Statement_Sequence (N)));
                  Prepend (Decl, Statements (Handled_Statement_Sequence (N)));
                  Mark_Rewrite_Insertion (Decl);
               else
                  --  If the accept statement has no body, there will be no
                  --  reference to the actuals, so no need to compute actual
                  --  subtypes.

                  return;
               end if;

            else
               Decl := Build_Actual_Subtype (T, Formal);
               Prepend (Decl, Declarations (N));
               Mark_Rewrite_Insertion (Decl);
            end if;

            --  The declaration uses the bounds of an existing object, and
            --  therefore needs no constraint checks.

            Analyze (Decl, Suppress => All_Checks);
            Set_Is_Actual_Subtype (Defining_Identifier (Decl));

            --  We need to freeze manually the generated type when it is
            --  inserted anywhere else than in a declarative part.

            if Present (First_Stmt) then
               Insert_List_Before_And_Analyze (First_Stmt,
                 Freeze_Entity (Defining_Identifier (Decl), N));

            --  Ditto if the type has a dynamic predicate, because the
            --  generated function will mention the actual subtype. The
            --  predicate may come from an explicit aspect of be inherited.

            elsif Has_Predicates (T) then
               Insert_List_After_And_Analyze (Decl,
                 Freeze_Entity (Defining_Identifier (Decl), N));
            end if;

            if Nkind (N) = N_Accept_Statement
              and then Expander_Active
            then
               Set_Actual_Subtype (Renamed_Object (Formal),
                 Defining_Identifier (Decl));
            else
               Set_Actual_Subtype (Formal, Defining_Identifier (Decl));
            end if;
         end if;

         Next_Formal (Formal);
      end loop;
   end Set_Actual_Subtypes;

   ---------------------
   -- Set_Formal_Mode --
   ---------------------

   procedure Set_Formal_Mode (Formal_Id : Entity_Id) is
      Spec : constant Node_Id   := Parent (Formal_Id);
      Id   : constant Entity_Id := Scope (Formal_Id);

   begin
      --  Note: we set Is_Known_Valid for IN parameters and IN OUT parameters
      --  since we ensure that corresponding actuals are always valid at the
      --  point of the call.

      if Out_Present (Spec) then
         if Is_Entry (Id)
           or else Is_Subprogram_Or_Generic_Subprogram (Id)
         then
            Set_Has_Out_Or_In_Out_Parameter (Id, True);
         end if;

         if Ekind (Id) in E_Function | E_Generic_Function then

            --  [IN] OUT parameters allowed for functions in Ada 2012

            if Ada_Version >= Ada_2012 then

               --  Even in Ada 2012 operators can only have IN parameters

               if Is_Operator_Symbol_Name (Chars (Scope (Formal_Id))) then
                  Error_Msg_N ("operators can only have IN parameters", Spec);
               end if;

               if In_Present (Spec) then
                  Mutate_Ekind (Formal_Id, E_In_Out_Parameter);
               else
                  Mutate_Ekind (Formal_Id, E_Out_Parameter);
               end if;

            --  But not in earlier versions of Ada

            else
               Error_Msg_N ("functions can only have IN parameters", Spec);
               Mutate_Ekind (Formal_Id, E_In_Parameter);
            end if;

         elsif In_Present (Spec) then
            Mutate_Ekind (Formal_Id, E_In_Out_Parameter);

         else
            Mutate_Ekind            (Formal_Id, E_Out_Parameter);
            Set_Never_Set_In_Source (Formal_Id, True);
            Set_Is_True_Constant    (Formal_Id, False);
            Set_Current_Value       (Formal_Id, Empty);
         end if;

      else
         Mutate_Ekind (Formal_Id, E_In_Parameter);
      end if;

      --  Set Is_Known_Non_Null for access parameters since the language
      --  guarantees that access parameters are always non-null. We also set
      --  Can_Never_Be_Null, since there is no way to change the value.

      if Nkind (Parameter_Type (Spec)) = N_Access_Definition then

         --  Ada 2005 (AI-231): In Ada 95, access parameters are always non-
         --  null; In Ada 2005, only if then null_exclusion is explicit.

         if Ada_Version < Ada_2005
           or else Can_Never_Be_Null (Etype (Formal_Id))
         then
            Set_Is_Known_Non_Null (Formal_Id);
            Set_Can_Never_Be_Null (Formal_Id);
         end if;

      --  Ada 2005 (AI-231): Null-exclusion access subtype

      elsif Is_Access_Type (Etype (Formal_Id))
        and then Can_Never_Be_Null (Etype (Formal_Id))
      then
         Set_Is_Known_Non_Null (Formal_Id);

         --  We can also set Can_Never_Be_Null (thus preventing some junk
         --  access checks) for the case of an IN parameter, which cannot
         --  be changed, or for an IN OUT parameter, which can be changed but
         --  not to a null value. But for an OUT parameter, the initial value
         --  passed in can be null, so we can't set this flag in that case.

         if Ekind (Formal_Id) /= E_Out_Parameter then
            Set_Can_Never_Be_Null (Formal_Id);
         end if;
      end if;

      Set_Mechanism (Formal_Id, Default_Mechanism);
      Set_Formal_Validity (Formal_Id);
   end Set_Formal_Mode;

   -------------------------
   -- Set_Formal_Validity --
   -------------------------

   procedure Set_Formal_Validity (Formal_Id : Entity_Id) is
   begin
      --  If no validity checking, then we cannot assume anything about the
      --  validity of parameters, since we do not know there is any checking
      --  of the validity on the call side.

      if not Validity_Checks_On then
         return;

      --  If validity checking for parameters is enabled, this means we are
      --  not supposed to make any assumptions about argument values.

      elsif Validity_Check_Parameters then
         return;

      --  If we are checking in parameters, we will assume that the caller is
      --  also checking parameters, so we can assume the parameter is valid.

      elsif Ekind (Formal_Id) = E_In_Parameter
        and then Validity_Check_In_Params
      then
         Set_Is_Known_Valid (Formal_Id, True);

      --  Similar treatment for IN OUT parameters

      elsif Ekind (Formal_Id) = E_In_Out_Parameter
        and then Validity_Check_In_Out_Params
      then
         Set_Is_Known_Valid (Formal_Id, True);
      end if;
   end Set_Formal_Validity;

   ------------------------
   -- Subtype_Conformant --
   ------------------------

   function Subtype_Conformant
     (New_Id                   : Entity_Id;
      Old_Id                   : Entity_Id;
      Skip_Controlling_Formals : Boolean := False) return Boolean
   is
      Result : Boolean;
   begin
      Check_Conformance (New_Id, Old_Id, Subtype_Conformant, False, Result,
        Skip_Controlling_Formals => Skip_Controlling_Formals);
      return Result;
   end Subtype_Conformant;

   ---------------------
   -- Type_Conformant --
   ---------------------

   function Type_Conformant
     (New_Id                   : Entity_Id;
      Old_Id                   : Entity_Id;
      Skip_Controlling_Formals : Boolean := False) return Boolean
   is
      Result : Boolean;
   begin
      May_Hide_Profile := False;
      Check_Conformance
        (New_Id, Old_Id, Type_Conformant, False, Result,
         Skip_Controlling_Formals => Skip_Controlling_Formals);
      return Result;
   end Type_Conformant;

   -------------------------------
   -- Valid_Operator_Definition --
   -------------------------------

   procedure Valid_Operator_Definition (Designator : Entity_Id) is
      N    : Integer := 0;
      F    : Entity_Id;
      Id   : constant Name_Id := Chars (Designator);
      N_OK : Boolean;

   begin
      F := First_Formal (Designator);
      while Present (F) loop
         N := N + 1;

         if Present (Default_Value (F)) then
            Error_Msg_N
              ("default values not allowed for operator parameters",
               Parent (F));

         --  For function instantiations that are operators, we must check
         --  separately that the corresponding generic only has in-parameters.
         --  For subprogram declarations this is done in Set_Formal_Mode. Such
         --  an error could not arise in earlier versions of the language.

         elsif Ekind (F) /= E_In_Parameter then
            Error_Msg_N ("operators can only have IN parameters", F);
         end if;

         Next_Formal (F);
      end loop;

      --  Verify that user-defined operators have proper number of arguments
      --  First case of operators which can only be unary

      if Id in Name_Op_Not | Name_Op_Abs then
         N_OK := (N = 1);

      --  Case of operators which can be unary or binary

      elsif Id in Name_Op_Add | Name_Op_Subtract then
         N_OK := (N in 1 .. 2);

      --  All other operators can only be binary

      else
         N_OK := (N = 2);
      end if;

      if not N_OK then
         Error_Msg_N
           ("incorrect number of arguments for operator", Designator);
      end if;

      if Id = Name_Op_Ne
        and then Base_Type (Etype (Designator)) = Standard_Boolean
        and then not Is_Intrinsic_Subprogram (Designator)
      then
         Error_Msg_N
           ("explicit definition of inequality not allowed", Designator);
      end if;
   end Valid_Operator_Definition;

end Sem_Ch6;
