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

with Aspects;   use Aspects;
with Atree;     use Atree;
with Checks;    use Checks;
with Contracts; use Contracts;
with Debug;     use Debug;
with Einfo;     use Einfo;
with Elists;    use Elists;
with Errout;    use Errout;
with Expander;  use Expander;
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 Rident;    use Rident;
with Rtsfind;   use Rtsfind;
with Sem;       use Sem;
with Sem_Aux;   use Sem_Aux;
with Sem_Cat;   use Sem_Cat;
with Sem_Ch3;   use Sem_Ch3;
with Sem_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.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_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
      Check_SPARK_05_Restriction ("abstract subprogram is not allowed", N);

      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.

   --  Start of processing for Analyze_Expression_Function

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

         --  Once the aspects of the generated body have been analyzed, create
         --  a copy for ASIS purposes and associate it with the original node.

         if Has_Aspects (N) then
            Set_Aspect_Specifications (Orig_N,
              New_Copy_List_Tree (Aspect_Specifications (N)));
         end if;

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

         --  Once the aspects of the generated spec have been analyzed, create
         --  a copy for ASIS purposes and associate it with the original node.

         if Has_Aspects (N) then
            Set_Aspect_Specifications (Orig_N,
              New_Copy_List_Tree (Aspect_Specifications (N)));
         end if;

         --  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 Inside_A_Generic then
            Set_Has_Completion (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;
            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_Aggregate_Accessibility (Aggr : Node_Id);
      --  Apply legality rule of 6.5 (5.8) 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_Aggregate_Accessibility --
      -----------------------------------

      procedure Check_Aggregate_Accessibility (Aggr : Node_Id) is
         Typ   : constant Entity_Id := Etype (Aggr);
         Assoc : Node_Id;
         Discr : Entity_Id;
         Expr  : Node_Id;
         Obj   : Node_Id;

      begin
         if Is_Record_Type (Typ) and then Has_Discriminants (Typ) then
            Discr := First_Discriminant (Typ);
            Assoc := First (Component_Associations (Aggr));
            while Present (Discr) loop
               if Ekind (Etype (Discr)) = E_Anonymous_Access_Type then
                  Expr := Expression (Assoc);

                  if Nkind (Expr) = N_Attribute_Reference
                    and then Attribute_Name (Expr) /= Name_Unrestricted_Access
                  then
                     Obj := Prefix (Expr);
                     while Nkind_In (Obj, N_Indexed_Component,
                                          N_Selected_Component)
                     loop
                        Obj := Prefix (Obj);
                     end loop;

                     --  Do not check aliased formals or function calls. A
                     --  run-time check may still be needed ???

                     if Is_Entity_Name (Obj)
                       and then Comes_From_Source (Obj)
                     then
                        if Is_Formal (Entity (Obj))
                           and then Is_Aliased (Entity (Obj))
                        then
                           null;

                        elsif Object_Access_Level (Obj) >
                                Scope_Depth (Scope (Scope_Id))
                        then
                           Error_Msg_N
                             ("access discriminant in return aggregate would "
                              & "be a dangling reference", Obj);
                        end if;
                     end if;
                  end if;
               end if;

               Next_Discriminant (Discr);
            end loop;
         end if;
      end Check_Aggregate_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_In (Expr, 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 not Nkind_In (Expr, 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);

            if Present (Expr) and then Nkind (Expr) = N_Aggregate then
               Check_Aggregate_Accessibility (Expr);
            end if;
         end if;

         --  RETURN only allowed in SPARK as the last statement in function

         if Nkind (Parent (N)) /= N_Handled_Sequence_Of_Statements
           and then
             (Nkind (Parent (Parent (N))) /= N_Subprogram_Body
               or else Present (Next (N)))
         then
            Check_SPARK_05_Restriction
              ("RETURN should be the last statement in function", N);
         end if;

      else
         Check_SPARK_05_Restriction ("extended RETURN is not allowed", N);
         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));
            Analyze (Obj_Decl);

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

         Apply_Constraint_Check (Expr, R_Type);

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

         if Ada_Version >= Ada_2005
           and then Ekind (R_Type) = E_Anonymous_Access_Type
         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 Object_Access_Level (Expr) >
                      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
         Set_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

         Set_Ekind          (Gen_Id,  Ekind (Body_Id));
         Set_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

            Set_Ekind (Gen_Id, Kind);
            Set_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

      Set_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);
         Set_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, and pragma arguments.

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

   begin
      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)
      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 Nam_In (Attribute_Name (P), 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);
         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_In (Entity (Selector_Name (P)), 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);
      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_In (N, 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, loops,
         --  and postconditions.

         for J in reverse 0 .. Scope_Stack.Last loop
            Result := Scope_Stack.Table (J).Entity;
            exit when not Ekind_In (Result, E_Block, E_Loop)
              and then Chars (Result) /= Name_uPostconditions;
         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 Comes_From_Source (N) then
         Error_Msg_N ("RETURN statement not allowed (No_Return)", 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 = E_Function or else Kind = E_Generic_Function then
         if not Returns_Object then
            Error_Msg_N ("missing expression in return from function", N);
         end if;

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

      elsif Kind = E_Entry or else Kind = 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 Ekind_In (Kind, E_Function, E_Generic_Function) then
         Analyze_Function_Return (N);

      elsif Ekind_In (Kind, 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
            Check_SPARK_05_Restriction
              ("access result is not allowed", Result_Definition (N));

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

            --  Unconstrained array as result is not allowed in SPARK

            if Is_Array_Type (Typ) and then not Is_Constrained (Typ) then
               Check_SPARK_05_Restriction
                 ("returning an unconstrained array is not allowed",
                  Result_Definition (N));
            end if;

            --  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_In (Parent (Parent (N)), 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);

      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.

      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.

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

      procedure Build_Subprogram_Declaration is
         procedure Move_Pragmas (From : Node_Id; To : Node_Id);
         --  Relocate certain categorization pragmas from the declarative list
         --  of subprogram body From and insert them after node To. The pragmas
         --  in question are:
         --    Ghost
         --    Volatile_Function
         --  Also 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.

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

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

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

            --  The destination node must be part of a list, as the pragmas are
            --  inserted after it.

            pragma Assert (Is_List_Member (To));

            --  Inspect the declarations of the subprogram body looking for
            --  specific pragmas.

            Decl := First (Declarations (N));
            while Present (Decl) loop
               Next_Decl := Next (Decl);

               if Nkind (Decl) = N_Pragma then
                  if Pragma_Name_Unmapped (Decl) = Name_SPARK_Mode then
                     Insert_After (To, New_Copy_Tree (Decl));

                  elsif Nam_In (Pragma_Name_Unmapped (Decl),
                                Name_Ghost,
                                Name_Volatile_Function)
                  then
                     Remove (Decl);
                     Insert_After (To, Decl);
                  end if;
               end if;

               Decl := Next_Decl;
            end loop;
         end Move_Pragmas;

         --  Local variables

         Decl      : Node_Id;
         Subp_Decl : Node_Id;

      --  Start of processing for Build_Subprogram_Declaration

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

           --  Avoid cases with no tasking support

           and then RTE_Available (RE_Current_Master)
           and then not Restriction_Active (No_Task_Hierarchy)
         then
            Decl :=
              Make_Object_Declaration (Loc,
                Defining_Identifier =>
                  Make_Defining_Identifier (Loc, Name_uMaster),
                Constant_Present => True,
                Object_Definition =>
                  New_Occurrence_Of (RTE (RE_Master_Id), Loc),
                Expression =>
                  Make_Explicit_Dereference (Loc,
                    New_Occurrence_Of (RTE (RE_Current_Master), 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_In
                   (Par, 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) then
            if Present (Spec_Id) then
               if Is_List_Member (N)
                 and then 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.

                  Set_Comes_From_Source (Subp, Comes_From_Source (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;

         --  Special checks in SPARK mode

         if Nkind (Body_Spec) = N_Function_Specification then

            --  In SPARK mode, last statement of a function should be a return

            declare
               Stat : constant Node_Id := Last_Source_Statement (HSS);
            begin
               if Present (Stat)
                 and then not Nkind_In (Stat, N_Simple_Return_Statement,
                                              N_Extended_Return_Statement)
               then
                  Check_SPARK_05_Restriction
                    ("last statement in function should be RETURN", Stat);
               end if;
            end;

         --  In SPARK mode, verify that a procedure has no return

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

            --  Would be nice to point to return statement here, can we
            --  borrow the Check_Returns procedure here ???

            if Return_Present (Id) then
               Check_SPARK_05_Restriction
                 ("procedure should not have RETURN", N);
            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 not Ekind_In (Subp_Id, 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;

      -------------------------------------
      -- 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_In (Entity (Node), E_Component, E_Discriminant) then
                  Mask_Type (Scope (Entity (Node)));
               end if;

            elsif Nkind_In (Node, 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;

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

            elsif not Present (Overridden_Operation (Spec_Id)) 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.

               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
               --  we are generating SPARK_For_C, create subprogram declaration
               --  to simplify subsequent C generation.

               elsif No (Spec_Id)
                 and then Modify_Tree_For_C
                 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 protected 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_Private_Protected_Declaration (N);
      end if;

      --  If we are generating C 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 Modify_Tree_For_C
        and then Present (Spec_Id)
        and then Ekind (Spec_Id) = E_Function
        and then Nkind (N) /= N_Subprogram_Body_Stub
        and then Rewritten_For_C (Spec_Id)
      then
         Set_Has_Completion (Spec_Id);

         Rewrite (N, Build_Procedure_Body_Form (Spec_Id, N));
         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);
         goto Leave;
      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 ASIS mode and in
         --  Compile_Only mode to enable the proper back-end type annotations.
         --  They are necessary in any case to insure order of elaboration
         --  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 ASIS_Mode
                      or else Operating_Mode = Check_Semantics)
         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.

            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;

         Set_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 (and indeed we definitely
            --  do not want these definitions -gnatc mode, because that would
            --  confuse ASIS).

            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

      --  Note: Normally we don't do any inlining if expansion is off, since
      --  we won't generate code in any case. An exception arises in GNATprove
      --  mode where we want to expand some calls in place, even with expansion
      --  disabled, since the inlining eases formal verification.

      if not GNATprove_Mode
        and then 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)
                 and then not Opt.Disable_FE_Inline_Always)
              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;

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

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

      --  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_In (Stm, N_Call_Marker, N_Label)
           or else Nkind (Stm) in 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
         Check_SPARK_05_Restriction ("null procedure is not allowed", N);

         --  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
      --  User-defined operator is not allowed in SPARK, except as a renaming

      if Nkind (Defining_Unit_Name (N)) = N_Defining_Operator_Symbol
        and then Nkind (Parent (N)) /= N_Subprogram_Renaming_Declaration
      then
         Check_SPARK_05_Restriction
           ("user-defined operator is not allowed", N);
      end if;

      --  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
         Set_Ekind (Designator, E_Function);
         Set_Mechanism (Designator, Default_Mechanism);
      else
         Set_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 not Nkind_In (Original_Node (Parent (N)),
                          N_Abstract_Subprogram_Declaration,
                          N_Formal_Abstract_Subprogram_Declaration,
                          N_Subprogram_Renaming_Declaration)
         then
            if Is_Abstract_Type (Etype (Designator))
              and then not Is_Interface (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 : Entity_Id;
         Id2 : Entity_Id) return Boolean;
      --  Determine whether the conventions of arbitrary entities Id1 and Id2
      --  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_In (Id1, E_Anonymous_Access_Subprogram_Type,
                           E_Subprogram_Type)
              or else
            Ekind_In (Id2, 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;

      --  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;
      Access_Types_Match : Boolean;
      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 %!");

            else
               Conformance_Error ("\calling conventions do not match!");
            end if;

            return;

         elsif 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
            Conformance_Error
              ("\formal subprograms are not subtype conformant "
               & "(RM 6.3.1 (17/3))");
         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 Null_Exclusion_Present (Parent (Old_Formal))
                 /=
               Null_Exclusion_Present (Parent (New_Formal))
            then
               --  Only give error if both come from source. This should be
               --  investigated some time, since it should not be needed ???

               if Comes_From_Source (Old_Formal)
                    and then
                  Comes_From_Source (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;
         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;

         Access_Types_Match := Ada_Version >= Ada_2005

           --  Ensure that this rule is only applied when New_Id is a
           --  renaming of Old_Id.

           and then Nkind (Parent (Parent (New_Id))) =
                      N_Subprogram_Renaming_Declaration
           and then Nkind (Name (Parent (Parent (New_Id)))) in N_Has_Entity
           and then Present (Entity (Name (Parent (Parent (New_Id)))))
           and then Entity (Name (Parent (Parent (New_Id)))) = Old_Id

           --  Now handle the allowed access-type case

           and then Is_Access_Type (Old_Formal_Base)
           and then Is_Access_Type (New_Formal_Base)

           --  The type kinds must match. The only exception occurs with
           --  multiple generics of the form:

           --   generic                    generic
           --     type F is private;         type A is private;
           --     type F_Ptr is access F;    type A_Ptr is access A;
           --     with proc F_P (X : F_Ptr); with proc A_P (X : A_Ptr);
           --   package F_Pack is ...      package A_Pack is
           --                                package F_Inst is
           --                                  new F_Pack (A, A_Ptr, A_P);

           --  When checking for conformance between the parameters of A_P
           --  and F_P, the type kinds of F_Ptr and A_Ptr will not match
           --  because the compiler has transformed A_Ptr into a subtype of
           --  F_Ptr. We catch this case in the code below.

           and then (Ekind (Old_Formal_Base) = Ekind (New_Formal_Base)
                      or else
                        (Is_Generic_Type (Old_Formal_Base)
                          and then Is_Generic_Type (New_Formal_Base)
                          and then Is_Internal (New_Formal_Base)
                          and then Etype (Etype (New_Formal_Base)) =
                                                          Old_Formal_Base))
               and then Directly_Designated_Type (Old_Formal_Base) =
                                    Directly_Designated_Type (New_Formal_Base)
           and then ((Is_Itype (Old_Formal_Base)
                       and then Can_Never_Be_Null (Old_Formal_Base))
                     or else
                      (Is_Itype (New_Formal_Base)
                        and then Can_Never_Be_Null (New_Formal_Base)));

         --  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)
               and then not Access_Types_Match
            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)
           and then not Access_Types_Match
         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 not Ekind_In (New_Id, 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
                        Error_Msg_PT (New_Id, Ultimate_Alias (Old_Id));
                     else
                        Conformance_Error
                          ("\mode of & does not match!", New_Formal);
                     end if;
                  end;
               end if;

               return;

            --  Part of mode conformance for access types is having the same
            --  constant modifier.

            elsif Access_Types_Match
              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 Ekind (Etype (Old_Formal)) = E_Anonymous_Access_Type
              and then Ekind (Etype (New_Formal)) = E_Anonymous_Access_Type
              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
            Analyze (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_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_In (Decl, 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;

      --  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. (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
                     (Nam_In (Chars (Overridden_Subp), Name_Initialize,
                                                       Name_Adjust,
                                                       Name_Finalize)
                      and then Present (Alias (Overridden_Subp))
                      and then not Is_Hidden (Alias (Overridden_Subp))))
      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_In (Last_Stm, N_Goto_Statement,
                                   N_Label,
                                   N_Object_Declaration)
               and then Exception_Junk (Last_Stm))
           or else Nkind (Last_Stm) in N_Push_xxx_Label
           or else Nkind (Last_Stm) in 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 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.

      -----------------------------------
      -- 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
            Prim_Param := Next (Prim_Param);
         end if;

         Iface_Param := 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_In (Def_Id, 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_In (Candidate, E_Entry, E_Procedure)
                    and then Is_Protected_Type (Typ)
                    and then Ekind (Formal) /= E_In_Out_Parameter
                    and then Ekind (Formal) /= E_Out_Parameter
                    and then Nkind (Parameter_Type (Parent (Formal))) /=
                                                       N_Access_Definition
                  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_In (Type_1, E_Anonymous_Access_Subprogram_Type,
                          E_Anonymous_Access_Protected_Subprogram_Type)
          and then
        Ekind_In (Type_2, 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;

         Set_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);
            Full_Subt   : constant Entity_Id := Available_View (Result_Subt);
            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 Has_Task (Full_Subt) then
               Discard :=
                 Add_Extra_Formal
                   (E, RTE (RE_Master_Id),
                    E, BIP_Formal_Suffix (BIP_Task_Master));
               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_In (Subp_Decl, 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.

      if Nkind (Decl) /= N_Subprogram_Declaration
        or else not Is_Record_Type (Typ)
        or else Is_Tagged_Type (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;

      --  No error detected

      else
         return;
      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_In (N, 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;

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

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

            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_Entity (P_Formal);
                        Next_Entity (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_In
                       (Parent (H),
                        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);

                        --  AI05-0073: extend this test to the case of a
                        --  function with a controlling access result.

                        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) return Boolean;
         --  Starting from the given parameters, check that all the parameters
         --  of two entries or subprograms are subtype 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.

         ---------------------------------
         -- Check_Conforming_Parameters --
         ---------------------------------

         function Check_Conforming_Parameters
           (E1_Param : Node_Id;
            E2_Param : Node_Id) 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 Ekind (Defining_Identifier (Param_E1)) /=
                    Ekind (Defining_Identifier (Param_E2))
                 or else not
                   Conforming_Types
                     (Find_Parameter_Type (Param_E1),
                      Find_Parameter_Type (Param_E2),
                      Subtype_Conformant)
               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)))))
               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)))))
               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;

      --  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 (Etype (First_Entity (E)))
         then
            if Scope (E) =
                 Scope (Corresponding_Concurrent_Type
                         (Etype (First_Entity (E))))
              and then
                Present
                  (Matching_Entry_Or_Subprogram
                     (Corresponding_Concurrent_Type (Etype (First_Entity (E))),
                      Subp => E))
            then
               Report_Conflict (E,
                 Matching_Entry_Or_Subprogram
                   (Corresponding_Concurrent_Type (Etype (First_Entity (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;

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

         --  Overloading is not allowed in SPARK, except for operators

         if Nkind (S) /= N_Defining_Operator_Symbol then
            Error_Msg_Sloc := Sloc (Homonym (S));
            Check_SPARK_05_Restriction
              ("overloading not allowed with entity#", S);
         end if;

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

            Formal_Type := Entity (Ptype);

            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 not Nkind_In
                              (Parent (T), 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 not Nkind_In (Parent (T), 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_In (Context, 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);
            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
            Check_SPARK_05_Restriction
              ("default expression is not allowed", Default);

            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_In (Scope (Formal), E_Function, E_Generic_Function) then

               --  A function cannot have a parameter of mode IN OUT or OUT
               --  (SPARK RM 6.1).

               if Ekind_In (Formal, 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(6)). -- ??? maybe 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;

      <<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_Before_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 Ekind_In (Id, E_Entry, E_Entry_Family)
           or else Is_Subprogram_Or_Generic_Subprogram (Id)
         then
            Set_Has_Out_Or_In_Out_Parameter (Id, True);
         end if;

         if Ekind_In (Id, 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
                  Set_Ekind (Formal_Id, E_In_Out_Parameter);
               else
                  Set_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);
               Set_Ekind (Formal_Id, E_In_Parameter);
            end if;

         elsif In_Present (Spec) then
            Set_Ekind (Formal_Id, E_In_Out_Parameter);

         else
            Set_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
         Set_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 Nam_In (Id, Name_Op_Not, Name_Op_Abs) then
         N_OK := (N = 1);

      --  Case of operators which can be unary or binary

      elsif Nam_In (Id, 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;
