------------------------------------------------------------------------------
--                                                                          --
--                         GNAT COMPILER COMPONENTS                         --
--                                                                          --
--                             S E M _ D I S P                              --
--                                                                          --
--                                 B o d y                                  --
--                                                                          --
--          Copyright (C) 1992-2022, 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 Debug;          use Debug;
with Elists;         use Elists;
with Einfo;          use Einfo;
with Einfo.Entities; use Einfo.Entities;
with Einfo.Utils;    use Einfo.Utils;
with Exp_Disp;       use Exp_Disp;
with Exp_Util;       use Exp_Util;
with Exp_Ch6;        use Exp_Ch6;
with Exp_Ch7;        use Exp_Ch7;
with Exp_Tss;        use Exp_Tss;
with Errout;         use Errout;
with Freeze;         use Freeze;
with Lib.Xref;       use Lib.Xref;
with Namet;          use Namet;
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 Sem;            use Sem;
with Sem_Aux;        use Sem_Aux;
with Sem_Ch6;        use Sem_Ch6;
with Sem_Ch8;        use Sem_Ch8;
with Sem_Eval;       use Sem_Eval;
with Sem_Type;       use Sem_Type;
with Sem_Util;       use Sem_Util;
with Snames;         use Snames;
with Sinfo;          use Sinfo;
with Sinfo.Nodes;    use Sinfo.Nodes;
with Sinfo.Utils;    use Sinfo.Utils;
with Tbuild;         use Tbuild;
with Uintp;          use Uintp;
with Warnsw;         use Warnsw;

package body Sem_Disp is

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

   procedure Add_Dispatching_Operation
     (Tagged_Type : Entity_Id;
      New_Op      : Entity_Id);
   --  Add New_Op in the list of primitive operations of Tagged_Type

   function Check_Controlling_Type
     (T    : Entity_Id;
      Subp : Entity_Id) return Entity_Id;
   --  T is the tagged type of a formal parameter or the result of Subp.
   --  If the subprogram has a controlling parameter or result that matches
   --  the type, then returns the tagged type of that parameter or result
   --  (returning the designated tagged type in the case of an access
   --  parameter); otherwise returns empty.

   function Find_Hidden_Overridden_Primitive (S : Entity_Id) return Entity_Id;
   --  [Ada 2012:AI-0125] Find an inherited hidden primitive of the dispatching
   --  type of S that has the same name of S, a type-conformant profile, an
   --  original corresponding operation O that is a primitive of a visible
   --  ancestor of the dispatching type of S and O is visible at the point of
   --  of declaration of S. If the entity is found the Alias of S is set to the
   --  original corresponding operation S and its Overridden_Operation is set
   --  to the found entity; otherwise return Empty.
   --
   --  This routine does not search for non-hidden primitives since they are
   --  covered by the normal Ada 2005 rules.

   function Is_Inherited_Public_Operation (Op : Entity_Id) return Boolean;
   --  Check whether a primitive operation is inherited from an operation
   --  declared in the visible part of its package.

   -------------------------------
   -- Add_Dispatching_Operation --
   -------------------------------

   procedure Add_Dispatching_Operation
     (Tagged_Type : Entity_Id;
      New_Op      : Entity_Id)
   is
      List : constant Elist_Id := Primitive_Operations (Tagged_Type);

   begin
      --  The dispatching operation may already be on the list, if it is the
      --  wrapper for an inherited function of a null extension (see Exp_Ch3
      --  for the construction of function wrappers). The list of primitive
      --  operations must not contain duplicates.

      --  The Default_Initial_Condition and invariant procedures are not added
      --  to the list of primitives even when they are generated for a tagged
      --  type. These routines must not be targets of dispatching calls and
      --  therefore must not appear in the dispatch table because they already
      --  utilize class-wide-precondition semantics to handle inheritance and
      --  overriding.

      if Is_Suitable_Primitive (New_Op) then
         Append_Unique_Elmt (New_Op, List);
      end if;
   end Add_Dispatching_Operation;

   --------------------------
   -- Covered_Interface_Op --
   --------------------------

   function Covered_Interface_Op (Prim : Entity_Id) return Entity_Id is
      Tagged_Type : constant Entity_Id := Find_Dispatching_Type (Prim);
      Elmt        : Elmt_Id;
      E           : Entity_Id;

   begin
      pragma Assert (Is_Dispatching_Operation (Prim));

      --  Although this is a dispatching primitive we must check if its
      --  dispatching type is available because it may be the primitive
      --  of a private type not defined as tagged in its partial view.

      if Present (Tagged_Type) and then Has_Interfaces (Tagged_Type) then

         --  If the tagged type is frozen then the internal entities associated
         --  with interfaces are available in the list of primitives of the
         --  tagged type and can be used to speed up this search.

         if Is_Frozen (Tagged_Type) then
            Elmt := First_Elmt (Primitive_Operations (Tagged_Type));
            while Present (Elmt) loop
               E := Node (Elmt);

               if Present (Interface_Alias (E))
                 and then Alias (E) = Prim
               then
                  return Interface_Alias (E);
               end if;

               Next_Elmt (Elmt);
            end loop;

         --  Otherwise we must collect all the interface primitives and check
         --  if the Prim overrides (implements) some interface primitive.

         else
            declare
               Ifaces_List : Elist_Id;
               Iface_Elmt  : Elmt_Id;
               Iface       : Entity_Id;
               Iface_Prim  : Entity_Id;

            begin
               Collect_Interfaces (Tagged_Type, Ifaces_List);
               Iface_Elmt := First_Elmt (Ifaces_List);
               while Present (Iface_Elmt) loop
                  Iface := Node (Iface_Elmt);

                  Elmt := First_Elmt (Primitive_Operations (Iface));
                  while Present (Elmt) loop
                     Iface_Prim := Node (Elmt);

                     if Chars (Iface_Prim) = Chars (Prim)
                       and then Is_Interface_Conformant
                                  (Tagged_Type, Iface_Prim, Prim)
                     then
                        return Iface_Prim;
                     end if;

                     Next_Elmt (Elmt);
                  end loop;

                  Next_Elmt (Iface_Elmt);
               end loop;
            end;
         end if;
      end if;

      return Empty;
   end Covered_Interface_Op;

   ----------------------------------
   -- Covered_Interface_Primitives --
   ----------------------------------

   function Covered_Interface_Primitives (Prim : Entity_Id) return Elist_Id is
      Tagged_Type : constant Entity_Id := Find_Dispatching_Type (Prim);
      Elmt        : Elmt_Id;
      E           : Entity_Id;
      Result      : Elist_Id := No_Elist;

   begin
      pragma Assert (Is_Dispatching_Operation (Prim));

      --  Although this is a dispatching primitive we must check if its
      --  dispatching type is available because it may be the primitive
      --  of a private type not defined as tagged in its partial view.

      if Present (Tagged_Type) and then Has_Interfaces (Tagged_Type) then

         --  If the tagged type is frozen then the internal entities associated
         --  with interfaces are available in the list of primitives of the
         --  tagged type and can be used to speed up this search.

         if Is_Frozen (Tagged_Type) then
            Elmt := First_Elmt (Primitive_Operations (Tagged_Type));
            while Present (Elmt) loop
               E := Node (Elmt);

               if Present (Interface_Alias (E))
                 and then Alias (E) = Prim
               then
                  if No (Result) then
                     Result := New_Elmt_List;
                  end if;

                  Append_Elmt (Interface_Alias (E), Result);
               end if;

               Next_Elmt (Elmt);
            end loop;

         --  Otherwise we must collect all the interface primitives and check
         --  whether the Prim overrides (implements) some interface primitive.

         else
            declare
               Ifaces_List : Elist_Id;
               Iface_Elmt  : Elmt_Id;
               Iface       : Entity_Id;
               Iface_Prim  : Entity_Id;

            begin
               Collect_Interfaces (Tagged_Type, Ifaces_List);

               Iface_Elmt := First_Elmt (Ifaces_List);
               while Present (Iface_Elmt) loop
                  Iface := Node (Iface_Elmt);

                  Elmt := First_Elmt (Primitive_Operations (Iface));
                  while Present (Elmt) loop
                     Iface_Prim := Node (Elmt);

                     if Chars (Iface_Prim) = Chars (Prim)
                       and then Is_Interface_Conformant
                                  (Tagged_Type, Iface_Prim, Prim)
                     then
                        if No (Result) then
                           Result := New_Elmt_List;
                        end if;

                        Append_Elmt (Iface_Prim, Result);
                     end if;

                     Next_Elmt (Elmt);
                  end loop;

                  Next_Elmt (Iface_Elmt);
               end loop;
            end;
         end if;
      end if;

      return Result;
   end Covered_Interface_Primitives;

   -------------------------------
   -- Check_Controlling_Formals --
   -------------------------------

   procedure Check_Controlling_Formals
     (Typ  : Entity_Id;
      Subp : Entity_Id)
   is
      Formal    : Entity_Id;
      Ctrl_Type : Entity_Id;

   begin
      Formal := First_Formal (Subp);
      while Present (Formal) loop
         Ctrl_Type := Check_Controlling_Type (Etype (Formal), Subp);

         if Present (Ctrl_Type) then

            --  Obtain the full type in case we are looking at an incomplete
            --  view.

            if Ekind (Ctrl_Type) = E_Incomplete_Type
              and then Present (Full_View (Ctrl_Type))
            then
               Ctrl_Type := Full_View (Ctrl_Type);
            end if;

            --  When controlling type is concurrent and declared within a
            --  generic or inside an instance use corresponding record type.

            if Is_Concurrent_Type (Ctrl_Type)
              and then Present (Corresponding_Record_Type (Ctrl_Type))
            then
               Ctrl_Type := Corresponding_Record_Type (Ctrl_Type);
            end if;

            if Ctrl_Type = Typ then
               Set_Is_Controlling_Formal (Formal);

               --  Ada 2005 (AI-231): Anonymous access types that are used in
               --  controlling parameters exclude null because it is necessary
               --  to read the tag to dispatch, and null has no tag.

               if Ekind (Etype (Formal)) = E_Anonymous_Access_Type then
                  Set_Can_Never_Be_Null (Etype (Formal));
                  Set_Is_Known_Non_Null (Etype (Formal));
               end if;

               --  Check that the parameter's nominal subtype statically
               --  matches the first subtype.

               if Ekind (Etype (Formal)) = E_Anonymous_Access_Type then
                  if not Subtypes_Statically_Match
                           (Typ, Designated_Type (Etype (Formal)))
                  then
                     Error_Msg_N
                       ("parameter subtype does not match controlling type",
                        Formal);
                  end if;

               --  Within a predicate function, the formal may be a subtype
               --  of a tagged type, given that the predicate is expressed
               --  in terms of the subtype.

               elsif not Subtypes_Statically_Match (Typ, Etype (Formal))
                 and then not Is_Predicate_Function (Subp)
               then
                  Error_Msg_N
                    ("parameter subtype does not match controlling type",
                     Formal);
               end if;

               if Present (Default_Value (Formal)) then

                  --  In Ada 2005, access parameters can have defaults

                  if Ekind (Etype (Formal)) = E_Anonymous_Access_Type
                    and then Ada_Version < Ada_2005
                  then
                     Error_Msg_N
                       ("default not allowed for controlling access parameter",
                        Default_Value (Formal));

                  elsif not Is_Tag_Indeterminate (Default_Value (Formal)) then
                     Error_Msg_N
                       ("default expression must be a tag indeterminate" &
                        " function call", Default_Value (Formal));
                  end if;
               end if;

            elsif Comes_From_Source (Subp) then
               Error_Msg_N
                 ("operation can be dispatching in only one type", Subp);
            end if;
         end if;

         Next_Formal (Formal);
      end loop;

      if Ekind (Subp) in E_Function | E_Generic_Function then
         Ctrl_Type := Check_Controlling_Type (Etype (Subp), Subp);

         if Present (Ctrl_Type) then
            if Ctrl_Type = Typ then
               Set_Has_Controlling_Result (Subp);

               --  Check that result subtype statically matches first subtype
               --  (Ada 2005): Subp may have a controlling access result.

               if Subtypes_Statically_Match (Typ, Etype (Subp))
                 or else (Ekind (Etype (Subp)) = E_Anonymous_Access_Type
                            and then
                              Subtypes_Statically_Match
                                (Typ, Designated_Type (Etype (Subp))))
               then
                  null;

               else
                  Error_Msg_N
                    ("result subtype does not match controlling type", Subp);
               end if;

            elsif Comes_From_Source (Subp) then
               Error_Msg_N
                 ("operation can be dispatching in only one type", Subp);
            end if;
         end if;
      end if;
   end Check_Controlling_Formals;

   ----------------------------
   -- Check_Controlling_Type --
   ----------------------------

   function Check_Controlling_Type
     (T    : Entity_Id;
      Subp : Entity_Id) return Entity_Id
   is
      Tagged_Type : Entity_Id := Empty;

   begin
      if Is_Tagged_Type (T) then
         if Is_First_Subtype (T) then
            Tagged_Type := T;
         else
            Tagged_Type := Base_Type (T);
         end if;

      --  If the type is incomplete, it may have been declared without a
      --  Tagged indication, but the full view may be tagged, in which case
      --  that is the controlling type of the subprogram. This is one of the
      --  approx. 579 places in the language where a lookahead would help.

      elsif Ekind (T) = E_Incomplete_Type
        and then Present (Full_View (T))
        and then Is_Tagged_Type (Full_View (T))
      then
         Set_Is_Tagged_Type (T);
         Tagged_Type := Full_View (T);

      elsif Ekind (T) = E_Anonymous_Access_Type
        and then Is_Tagged_Type (Designated_Type (T))
      then
         if Ekind (Designated_Type (T)) /= E_Incomplete_Type then
            if Is_First_Subtype (Designated_Type (T)) then
               Tagged_Type := Designated_Type (T);
            else
               Tagged_Type := Base_Type (Designated_Type (T));
            end if;

         --  Ada 2005: an incomplete type can be tagged. An operation with an
         --  access parameter of the type is dispatching.

         elsif Scope (Designated_Type (T)) = Current_Scope then
            Tagged_Type := Designated_Type (T);

         --  Ada 2005 (AI-50217)

         elsif From_Limited_With (Designated_Type (T))
           and then Has_Non_Limited_View (Designated_Type (T))
           and then Scope (Designated_Type (T)) = Scope (Subp)
         then
            if Is_First_Subtype (Non_Limited_View (Designated_Type (T))) then
               Tagged_Type := Non_Limited_View (Designated_Type (T));
            else
               Tagged_Type := Base_Type (Non_Limited_View
                                         (Designated_Type (T)));
            end if;
         end if;
      end if;

      if No (Tagged_Type) or else Is_Class_Wide_Type (Tagged_Type) then
         return Empty;

      --  In the special case of a protected subprogram of a tagged protected
      --  type that has a formal of a tagged type (or access formal whose type
      --  designates a tagged type), such a formal is not controlling unless
      --  it's of the protected type's corresponding record type. The latter
      --  can occur for the special wrapper subprograms created for protected
      --  subprograms. Such subprograms may occur in the same scope where some
      --  formal's tagged type is declared, and we don't want formals of that
      --  tagged type being marked as controlling, for one thing because they
      --  aren't controlling from the language point of view, but also because
      --  this can cause errors for access formals when conformance is checked
      --  between the spec and body of the protected subprogram (null-exclusion
      --  status of the formals may be set differently, which is the case that
      --  led to adding this check).

      elsif Is_Subprogram (Subp)
        and then Present (Protected_Subprogram (Subp))
        and then Ekind (Scope (Protected_Subprogram (Subp))) = E_Protected_Type
        and then
          Base_Type (Tagged_Type)
            /= Corresponding_Record_Type (Scope (Protected_Subprogram (Subp)))
      then
         return Empty;

      --  The dispatching type and the primitive operation must be defined in
      --  the same scope, except in the case of internal operations and formal
      --  abstract subprograms.

      elsif ((Scope (Subp) = Scope (Tagged_Type) or else Is_Internal (Subp))
               and then (not Is_Generic_Type (Tagged_Type)
                          or else not Comes_From_Source (Subp)))
        or else
          (Is_Formal_Subprogram (Subp) and then Is_Abstract_Subprogram (Subp))
        or else
          (Nkind (Parent (Parent (Subp))) = N_Subprogram_Renaming_Declaration
            and then
              Present (Corresponding_Formal_Spec (Parent (Parent (Subp))))
            and then
              Is_Abstract_Subprogram (Subp))
      then
         return Tagged_Type;

      else
         return Empty;
      end if;
   end Check_Controlling_Type;

   ----------------------------
   -- Check_Dispatching_Call --
   ----------------------------

   procedure Check_Dispatching_Call (N : Node_Id) is
      Loc                    : constant Source_Ptr := Sloc (N);
      Actual                 : Node_Id;
      Formal                 : Entity_Id;
      Control                : Node_Id := Empty;
      Func                   : Entity_Id;
      Subp_Entity            : Entity_Id;
      Indeterm_Ancestor_Call : Boolean := False;
      Indeterm_Ctrl_Type     : Entity_Id := Empty; -- init to avoid warning

      Static_Tag : Node_Id := Empty;
      --  If a controlling formal has a statically tagged actual, the tag of
      --  this actual is to be used for any tag-indeterminate actual.

      procedure Check_Direct_Call;
      --  In the case when the controlling actual is a class-wide type whose
      --  root type's completion is a task or protected type, the call is in
      --  fact direct. This routine detects the above case and modifies the
      --  call accordingly.

      procedure Check_Dispatching_Context (Call : Node_Id);
      --  If the call is tag-indeterminate and the entity being called is
      --  abstract, verify that the context is a call that will eventually
      --  provide a tag for dispatching, or has provided one already.

      -----------------------
      -- Check_Direct_Call --
      -----------------------

      procedure Check_Direct_Call is
         Typ : Entity_Id := Etype (Control);
      begin
         --  Predefined primitives do not receive wrappers since they are built
         --  from scratch for the corresponding record of synchronized types.
         --  Equality is in general predefined, but is excluded from the check
         --  when it is user-defined.

         if Is_Predefined_Dispatching_Operation (Subp_Entity)
           and then not Is_User_Defined_Equality (Subp_Entity)
         then
            return;
         end if;

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

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

         if Is_Concurrent_Type (Typ)
              and then
            Present (Corresponding_Record_Type (Typ))
         then
            Typ := Corresponding_Record_Type (Typ);

            --  The concurrent record's list of primitives should contain a
            --  wrapper for the entity of the call, retrieve it.

            declare
               Prim          : Entity_Id;
               Prim_Elmt     : Elmt_Id;
               Wrapper_Found : Boolean := False;

            begin
               Prim_Elmt := First_Elmt (Primitive_Operations (Typ));
               while Present (Prim_Elmt) loop
                  Prim := Node (Prim_Elmt);

                  if Is_Primitive_Wrapper (Prim)
                    and then Wrapped_Entity (Prim) = Subp_Entity
                  then
                     Wrapper_Found := True;
                     exit;
                  end if;

                  Next_Elmt (Prim_Elmt);
               end loop;

               --  A primitive declared between two views should have a
               --  corresponding wrapper.

               pragma Assert (Wrapper_Found);

               --  Modify the call by setting the proper entity

               Set_Entity (Name (N), Prim);
            end;
         end if;
      end Check_Direct_Call;

      -------------------------------
      -- Check_Dispatching_Context --
      -------------------------------

      procedure Check_Dispatching_Context (Call : Node_Id) is
         Subp : constant Entity_Id := Entity (Name (Call));

         procedure Abstract_Context_Error;
         --  Error for abstract call dispatching on result is not dispatching

         function Has_Controlling_Current_Instance_Actual_In_DIC
           (Call : Node_Id) return Boolean;
         --  Return True if the subprogram call Call has a controlling actual
         --  given directly by a current instance referenced within a DIC
         --  aspect.

         ----------------------------
         -- Abstract_Context_Error --
         ----------------------------

         procedure Abstract_Context_Error is
         begin
            if Ekind (Subp) = E_Function then
               Error_Msg_N
                 ("call to abstract function must be dispatching", N);

            --  This error can occur for a procedure in the case of a call to
            --  an abstract formal procedure with a statically tagged operand.

            else
               Error_Msg_N
                 ("call to abstract procedure must be dispatching", N);
            end if;
         end Abstract_Context_Error;

         ----------------------------------------
         -- Has_Current_Instance_Actual_In_DIC --
         ----------------------------------------

         function Has_Controlling_Current_Instance_Actual_In_DIC
           (Call : Node_Id) return Boolean
         is
            A : Node_Id;
            F : Entity_Id;
         begin
            F := First_Formal (Subp_Entity);
            A := First_Actual (Call);

            while Present (F) loop

               --  Return True if the actual denotes a current instance (which
               --  will be represented by an in-mode formal of the enclosing
               --  DIC_Procedure) passed to a controlling formal. We don't have
               --  to worry about controlling access formals here, because its
               --  illegal to apply Access (etc.) attributes to a current
               --  instance within an aspect (by AI12-0068).

               if Is_Controlling_Formal (F)
                 and then Nkind (A) = N_Identifier
                 and then Ekind (Entity (A)) = E_In_Parameter
                 and then Is_Subprogram (Scope (Entity (A)))
                 and then Is_DIC_Procedure (Scope (Entity (A)))
               then
                  return True;
               end if;

               Next_Formal (F);
               Next_Actual (A);
            end loop;

            return False;
         end Has_Controlling_Current_Instance_Actual_In_DIC;

         --  Local variables

         Scop : constant Entity_Id := Current_Scope_No_Loops;
         Typ  : constant Entity_Id := Etype (Subp);
         Par  : Node_Id;

      --  Start of processing for Check_Dispatching_Context

      begin
         --  Skip checking context of dispatching calls during preanalysis of
         --  class-wide conditions since at that stage the expression is not
         --  installed yet on its definite context.

         if Inside_Class_Condition_Preanalysis then
            return;
         end if;

         --  If the called subprogram is a private overriding, replace it
         --  with its alias, which has the correct body. Verify that the
         --  two subprograms have the same controlling type (this is not the
         --  case for an inherited subprogram that has become abstract).

         if Is_Abstract_Subprogram (Subp)
           and then No (Controlling_Argument (Call))
         then
            if Present (Alias (Subp))
              and then not Is_Abstract_Subprogram (Alias (Subp))
              and then No (DTC_Entity (Subp))
              and then Find_Dispatching_Type (Subp) =
                         Find_Dispatching_Type (Alias (Subp))
            then
               --  Private overriding of inherited abstract operation, call is
               --  legal.

               Set_Entity (Name (N), Alias (Subp));
               return;

            --  If this is a pre/postcondition for an abstract subprogram,
            --  it may call another abstract function that is a primitive
            --  of an abstract type. The call is nondispatching but will be
            --  legal in overridings of the operation. However, if the call
            --  is tag-indeterminate we want to continue with with the error
            --  checking below, as this case is illegal even for abstract
            --  subprograms (see AI12-0170).

            --  Similarly, as per AI12-0412, a nonabstract subprogram may
            --  have a class-wide pre/postcondition that includes a call to
            --  an abstract primitive of the subprogram's controlling type.
            --  Certain operations (nondispatching calls, 'Access, use as
            --  a generic actual) applied to such a nonabstract subprogram
            --  are illegal in the case where the type is abstract (see
            --  RM 6.1.1(18.2/5)).

            elsif Is_Subprogram (Scop)
              and then not Is_Tag_Indeterminate (N)
              and then In_Pre_Post_Condition (Call, Class_Wide_Only => True)

              --  The tagged type associated with the called subprogram must be
              --  the same as that of the subprogram with a class-wide aspect.

              and then Is_Dispatching_Operation (Scop)
              and then
                Find_Dispatching_Type (Subp) = Find_Dispatching_Type (Scop)
            then
               null;

            --  Similarly to the dispensation for postconditions, a call to
            --  an abstract function within a Default_Initial_Condition aspect
            --  can be legal when passed a current instance of the type. Such
            --  a call will be effectively mapped to a call to a primitive of
            --  a descendant type (see AI12-0397, as well as AI12-0170), so
            --  doesn't need to be dispatching. We test for being within a DIC
            --  procedure, since that's where the call will be analyzed.

            elsif Is_Subprogram (Scop)
              and then Is_DIC_Procedure (Scop)
              and then Has_Controlling_Current_Instance_Actual_In_DIC (Call)
            then
               null;

            elsif Ekind (Current_Scope) = E_Function
              and then Nkind (Unit_Declaration_Node (Scop)) =
                         N_Generic_Subprogram_Declaration
            then
               null;

            else
               --  We need to determine whether the context of the call
               --  provides a tag to make the call dispatching. This requires
               --  the call to be the actual in an enclosing call, and that
               --  actual must be controlling. If the call is an operand of
               --  equality, the other operand must not be abstract.

               if not Is_Tagged_Type (Typ)
                 and then not
                   (Ekind (Typ) = E_Anonymous_Access_Type
                     and then Is_Tagged_Type (Designated_Type (Typ)))
               then
                  Abstract_Context_Error;
                  return;
               end if;

               Par := Parent (Call);

               if Nkind (Par) = N_Parameter_Association then
                  Par := Parent (Par);
               end if;

               if Nkind (Par) = N_Qualified_Expression
                 or else Nkind (Par) = N_Unchecked_Type_Conversion
               then
                  Par := Parent (Par);
               end if;

               if Nkind (Par) in N_Subprogram_Call
                 and then Is_Entity_Name (Name (Par))
               then
                  declare
                     Enc_Subp : constant Entity_Id := Entity (Name (Par));
                     A        : Node_Id;
                     F        : Entity_Id;
                     Control  : Entity_Id;
                     Ret_Type : Entity_Id;

                  begin
                     --  Find controlling formal that can provide tag for the
                     --  tag-indeterminate actual. The corresponding actual
                     --  must be the corresponding class-wide type.

                     F := First_Formal (Enc_Subp);
                     A := First_Actual (Par);

                     --  Find controlling type of call. Dereference if function
                     --  returns an access type.

                     Ret_Type := Etype (Call);
                     if Is_Access_Type (Etype (Call)) then
                        Ret_Type := Designated_Type (Ret_Type);
                     end if;

                     while Present (F) loop
                        Control := Etype (A);

                        if Is_Access_Type (Control) then
                           Control := Designated_Type (Control);
                        end if;

                        if Is_Controlling_Formal (F)
                          and then not (Call = A or else Parent (Call) = A)
                          and then Control = Class_Wide_Type (Ret_Type)
                        then
                           return;
                        end if;

                        Next_Formal (F);
                        Next_Actual (A);
                     end loop;

                     if Nkind (Par) = N_Function_Call
                       and then Is_Tag_Indeterminate (Par)
                     then
                        --  The parent may be an actual of an enclosing call

                        Check_Dispatching_Context (Par);
                        return;

                     else
                        Error_Msg_N
                          ("call to abstract function must be dispatching",
                           Call);
                        return;
                     end if;
                  end;

               --  For equality operators, one of the operands must be
               --  statically or dynamically tagged.

               elsif Nkind (Par) in N_Op_Eq | N_Op_Ne then
                  if N = Right_Opnd (Par)
                    and then Is_Tag_Indeterminate (Left_Opnd (Par))
                  then
                     Abstract_Context_Error;

                  elsif N = Left_Opnd (Par)
                    and then Is_Tag_Indeterminate (Right_Opnd (Par))
                  then
                     Abstract_Context_Error;
                  end if;

                  return;

               --  The left-hand side of an assignment provides the tag

               elsif Nkind (Par) = N_Assignment_Statement then
                  return;

               else
                  Abstract_Context_Error;
               end if;
            end if;
         end if;
      end Check_Dispatching_Context;

   --  Start of processing for Check_Dispatching_Call

   begin
      --  Find a controlling argument, if any

      if Present (Parameter_Associations (N)) then
         Subp_Entity := Entity (Name (N));

         Actual := First_Actual (N);
         Formal := First_Formal (Subp_Entity);
         while Present (Actual) loop
            Control := Find_Controlling_Arg (Actual);
            exit when Present (Control);

            --  Check for the case where the actual is a tag-indeterminate call
            --  whose result type is different than the tagged type associated
            --  with the containing call, but is an ancestor of the type.

            if Is_Controlling_Formal (Formal)
              and then Is_Tag_Indeterminate (Actual)
              and then Base_Type (Etype (Actual)) /= Base_Type (Etype (Formal))
              and then Is_Ancestor (Etype (Actual), Etype (Formal))
            then
               Indeterm_Ancestor_Call := True;
               Indeterm_Ctrl_Type     := Etype (Formal);

            --  If the formal is controlling but the actual is not, the type
            --  of the actual is statically known, and may be used as the
            --  controlling tag for some other tag-indeterminate actual.

            elsif Is_Controlling_Formal (Formal)
              and then Is_Entity_Name (Actual)
              and then Is_Tagged_Type (Etype (Actual))
            then
               Static_Tag := Actual;
            end if;

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

         --  If the call doesn't have a controlling actual but does have an
         --  indeterminate actual that requires dispatching treatment, then an
         --  object is needed that will serve as the controlling argument for
         --  a dispatching call on the indeterminate actual. This can occur
         --  in the unusual situation of a default actual given by a tag-
         --  indeterminate call and where the type of the call is an ancestor
         --  of the type associated with a containing call to an inherited
         --  operation (see AI-239).

         --  Rather than create an object of the tagged type, which would
         --  be problematic for various reasons (default initialization,
         --  discriminants), the tag of the containing call's associated
         --  tagged type is directly used to control the dispatching.

         if No (Control)
           and then Indeterm_Ancestor_Call
           and then No (Static_Tag)
         then
            Control :=
              Make_Attribute_Reference (Loc,
                Prefix         => New_Occurrence_Of (Indeterm_Ctrl_Type, Loc),
                Attribute_Name => Name_Tag);

            Analyze (Control);
         end if;

         if Present (Control) then

            --  Verify that no controlling arguments are statically tagged

            if Debug_Flag_E then
               Write_Str ("Found Dispatching call");
               Write_Int (Int (N));
               Write_Eol;
            end if;

            Actual := First_Actual (N);
            while Present (Actual) loop
               if Actual /= Control then

                  if not Is_Controlling_Actual (Actual) then
                     null; -- Can be anything

                  elsif Is_Dynamically_Tagged (Actual) then
                     null; -- Valid parameter

                  elsif Is_Tag_Indeterminate (Actual) then

                     --  The tag is inherited from the enclosing call (the node
                     --  we are currently analyzing). Explicitly expand the
                     --  actual, since the previous call to Expand (from
                     --  Resolve_Call) had no way of knowing about the
                     --  required dispatching.

                     Propagate_Tag (Control, Actual);

                  else
                     Error_Msg_N
                       ("controlling argument is not dynamically tagged",
                        Actual);
                     return;
                  end if;
               end if;

               Next_Actual (Actual);
            end loop;

            --  Mark call as a dispatching call

            Set_Controlling_Argument (N, Control);
            Check_Restriction (No_Dispatching_Calls, N);

            --  The dispatching call may need to be converted into a direct
            --  call in certain cases.

            Check_Direct_Call;

         --  If there is a statically tagged actual and a tag-indeterminate
         --  call to a function of the ancestor (such as that provided by a
         --  default), then treat this as a dispatching call and propagate
         --  the tag to the tag-indeterminate call(s).

         elsif Present (Static_Tag) and then Indeterm_Ancestor_Call then
            Control :=
              Make_Attribute_Reference (Loc,
                Prefix         =>
                  New_Occurrence_Of (Etype (Static_Tag), Loc),
                Attribute_Name => Name_Tag);

            Analyze (Control);

            Actual := First_Actual (N);
            Formal := First_Formal (Subp_Entity);
            while Present (Actual) loop
               if Is_Tag_Indeterminate (Actual)
                 and then Is_Controlling_Formal (Formal)
               then
                  Propagate_Tag (Control, Actual);
               end if;

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

            Check_Dispatching_Context (N);

         elsif Nkind (N) /= N_Function_Call then

            --  The call is not dispatching, so check that there aren't any
            --  tag-indeterminate abstract calls left among its actuals.

            Actual := First_Actual (N);
            while Present (Actual) loop
               if Is_Tag_Indeterminate (Actual) then

                  --  Function call case

                  if Nkind (Original_Node (Actual)) = N_Function_Call then
                     Func := Entity (Name (Original_Node (Actual)));

                  --  If the actual is an attribute then it can't be abstract
                  --  (the only current case of a tag-indeterminate attribute
                  --  is the stream Input attribute).

                  elsif Nkind (Original_Node (Actual)) = N_Attribute_Reference
                  then
                     Func := Empty;

                  --  Ditto if it is an explicit dereference

                  elsif Nkind (Original_Node (Actual)) = N_Explicit_Dereference
                  then
                     Func := Empty;

                  --  Only other possibility is a qualified expression whose
                  --  constituent expression is itself a call.

                  else
                     Func :=
                       Entity (Name (Original_Node
                         (Expression (Original_Node (Actual)))));
                  end if;

                  if Present (Func) and then Is_Abstract_Subprogram (Func) then
                     Error_Msg_N
                       ("call to abstract function must be dispatching",
                        Actual);
                  end if;
               end if;

               Next_Actual (Actual);
            end loop;

            Check_Dispatching_Context (N);

         elsif Nkind (Parent (N)) in N_Subexpr then
            Check_Dispatching_Context (N);

         elsif Nkind (Parent (N)) = N_Assignment_Statement
           and then Is_Class_Wide_Type (Etype (Name (Parent (N))))
         then
            return;

         elsif Is_Abstract_Subprogram (Subp_Entity) then
            Check_Dispatching_Context (N);
            return;
         end if;

         --  If this is a nondispatching call to a nonabstract subprogram
         --  and the subprogram has any Pre'Class or Post'Class aspects with
         --  nonstatic values, then report an error. This is specified by
         --  RM 6.1.1(18.2/5) (by AI12-0412).

         --  Skip reporting this error on helpers and indirect-call wrappers
         --  built to support class-wide preconditions.

         if No (Control)
           and then not Is_Abstract_Subprogram (Subp_Entity)
           and then
             Is_Prim_Of_Abst_Type_With_Nonstatic_CW_Pre_Post (Subp_Entity)
           and then not
             (Is_Subprogram (Current_Scope)
                and then
              Present (Class_Preconditions_Subprogram (Current_Scope)))
         then
            Error_Msg_N
              ("nondispatching call to nonabstract subprogram of "
                & "abstract type with nonstatic class-wide "
                & "pre/postconditions",
               N);
         end if;

      else
         --  If dispatching on result, the enclosing call, if any, will
         --  determine the controlling argument. Otherwise this is the
         --  primitive operation of the root type.

         Check_Dispatching_Context (N);
      end if;
   end Check_Dispatching_Call;

   ---------------------------------
   -- Check_Dispatching_Operation --
   ---------------------------------

   procedure Check_Dispatching_Operation (Subp, Old_Subp : Entity_Id) is
      function Is_Access_To_Subprogram_Wrapper (E : Entity_Id) return Boolean;
      --  Return True if E is an access to subprogram wrapper

      procedure Warn_On_Late_Primitive_After_Private_Extension
        (Typ  : Entity_Id;
         Prim : Entity_Id);
      --  Prim is a dispatching primitive of the tagged type Typ. Warn on Prim
      --  if it is a public primitive defined after some private extension of
      --  the tagged type.

      -------------------------------------
      -- Is_Access_To_Subprogram_Wrapper --
      -------------------------------------

      function Is_Access_To_Subprogram_Wrapper (E : Entity_Id) return Boolean
      is
         Decl_N : constant Node_Id := Unit_Declaration_Node (E);
         Par_N  : constant Node_Id := Parent (List_Containing (Decl_N));

      begin
         --  Access to subprogram wrappers are declared in the freezing actions

         return Nkind (Par_N) = N_Freeze_Entity
           and then Ekind (Entity (Par_N)) = E_Access_Subprogram_Type;
      end Is_Access_To_Subprogram_Wrapper;

      ----------------------------------------------------
      -- Warn_On_Late_Primitive_After_Private_Extension --
      ----------------------------------------------------

      procedure Warn_On_Late_Primitive_After_Private_Extension
        (Typ  : Entity_Id;
         Prim : Entity_Id)
      is
         E : Entity_Id;

      begin
         if Warn_On_Late_Primitives
           and then Comes_From_Source (Prim)
           and then Has_Private_Extension (Typ)
           and then Is_Package_Or_Generic_Package (Current_Scope)
           and then not In_Private_Part (Current_Scope)
         then
            E := Next_Entity (Typ);

            while E /= Prim loop
               if Ekind (E) = E_Record_Type_With_Private
                 and then Etype (E) = Typ
               then
                  Error_Msg_Name_1 := Chars (Typ);
                  Error_Msg_Name_2 := Chars (E);
                  Error_Msg_Sloc := Sloc (E);
                  Error_Msg_N
                    ("?j?primitive of type % defined after private extension "
                     & "% #?", Prim);
                  Error_Msg_Name_1 := Chars (Prim);
                  Error_Msg_Name_2 := Chars (E);
                  Error_Msg_N
                    ("\spec of % should appear before declaration of type %!",
                     Prim);
                  exit;
               end if;

               Next_Entity (E);
            end loop;
         end if;
      end Warn_On_Late_Primitive_After_Private_Extension;

      --  Local variables

      Body_Is_Last_Primitive : Boolean   := False;
      Has_Dispatching_Parent : Boolean   := False;
      Ovr_Subp               : Entity_Id := Empty;
      Tagged_Type            : Entity_Id;

   --  Start of processing for Check_Dispatching_Operation

   begin
      if Ekind (Subp) not in E_Function | E_Procedure then
         return;

      --  The Default_Initial_Condition procedure is not a primitive subprogram
      --  even if it relates to a tagged type. This routine is not meant to be
      --  inherited or overridden.

      elsif Is_DIC_Procedure (Subp) then
         return;

      --  The "partial" and "full" type invariant procedures are not primitive
      --  subprograms even if they relate to a tagged type. These routines are
      --  not meant to be inherited or overridden.

      elsif Is_Invariant_Procedure (Subp)
        or else Is_Partial_Invariant_Procedure (Subp)
      then
         return;

      --  Wrappers of access to subprograms are not primitive subprograms.

      elsif Is_Wrapper (Subp)
        and then Is_Access_To_Subprogram_Wrapper (Subp)
      then
         return;
      end if;

      Set_Is_Dispatching_Operation (Subp, False);
      Tagged_Type := Find_Dispatching_Type (Subp);

      --  Ada 2005 (AI-345): Use the corresponding record (if available).
      --  Required because primitives of concurrent types are attached
      --  to the corresponding record (not to the concurrent type).

      if Ada_Version >= Ada_2005
        and then Present (Tagged_Type)
        and then Is_Concurrent_Type (Tagged_Type)
        and then Present (Corresponding_Record_Type (Tagged_Type))
      then
         Tagged_Type := Corresponding_Record_Type (Tagged_Type);
      end if;

      --  (AI-345): The task body procedure is not a primitive of the tagged
      --  type

      if Present (Tagged_Type)
        and then Is_Concurrent_Record_Type (Tagged_Type)
        and then Present (Corresponding_Concurrent_Type (Tagged_Type))
        and then Is_Task_Type (Corresponding_Concurrent_Type (Tagged_Type))
        and then Subp = Get_Task_Body_Procedure
                          (Corresponding_Concurrent_Type (Tagged_Type))
      then
         return;
      end if;

      --  If Subp is derived from a dispatching operation then it should
      --  always be treated as dispatching. In this case various checks
      --  below will be bypassed. Makes sure that late declarations for
      --  inherited private subprograms are treated as dispatching, even
      --  if the associated tagged type is already frozen.

      Has_Dispatching_Parent :=
        Present (Alias (Subp))
          and then Is_Dispatching_Operation (Alias (Subp));

      if No (Tagged_Type) then

         --  Ada 2005 (AI-251): Check that Subp is not a primitive associated
         --  with an abstract interface type unless the interface acts as a
         --  parent type in a derivation. If the interface type is a formal
         --  type then the operation is not primitive and therefore legal.

         declare
            E   : Entity_Id;
            Typ : Entity_Id;

         begin
            E := First_Entity (Subp);
            while Present (E) loop

               --  For an access parameter, check designated type

               if Ekind (Etype (E)) = E_Anonymous_Access_Type then
                  Typ := Designated_Type (Etype (E));
               else
                  Typ := Etype (E);
               end if;

               if Comes_From_Source (Subp)
                 and then Is_Interface (Typ)
                 and then not Is_Class_Wide_Type (Typ)
                 and then not Is_Derived_Type (Typ)
                 and then not Is_Generic_Type (Typ)
                 and then not In_Instance
               then
                  Error_Msg_N ("??declaration of& is too late!", Subp);
                  Error_Msg_NE -- CODEFIX??
                    ("\??spec should appear immediately after declaration of "
                     & "& !", Subp, Typ);
                  exit;
               end if;

               Next_Entity (E);
            end loop;

            --  In case of functions check also the result type

            if Ekind (Subp) = E_Function then
               if Is_Access_Type (Etype (Subp)) then
                  Typ := Designated_Type (Etype (Subp));
               else
                  Typ := Etype (Subp);
               end if;

               --  The following should be better commented, especially since
               --  we just added several new conditions here ???

               if Comes_From_Source (Subp)
                 and then Is_Interface (Typ)
                 and then not Is_Class_Wide_Type (Typ)
                 and then not Is_Derived_Type (Typ)
                 and then not Is_Generic_Type (Typ)
                 and then not In_Instance
               then
                  Error_Msg_N ("??declaration of& is too late!", Subp);
                  Error_Msg_NE
                    ("\??spec should appear immediately after declaration of "
                     & "& !", Subp, Typ);
               end if;
            end if;
         end;

         return;

      --  The subprograms build internally after the freezing point (such as
      --  init procs, interface thunks, type support subprograms, and Offset
      --  to top functions for accessing interface components in variable
      --  size tagged types) are not primitives.

      elsif Is_Frozen (Tagged_Type)
        and then not Comes_From_Source (Subp)
        and then not Has_Dispatching_Parent
      then
         --  Complete decoration of internally built subprograms that override
         --  a dispatching primitive. These entities correspond with the
         --  following cases:

         --  1. Ada 2005 (AI-391): Wrapper functions built by the expander
         --     to override functions of nonabstract null extensions. These
         --     primitives were added to the list of primitives of the tagged
         --     type by Make_Controlling_Function_Wrappers. However, attribute
         --     Is_Dispatching_Operation must be set to true.

         --  2. Ada 2005 (AI-251): Wrapper procedures of null interface
         --     primitives.

         --  3. Subprograms associated with stream attributes (built by
         --     New_Stream_Subprogram) or with the Put_Image attribute.

         --  4. Wrappers built for inherited operations with inherited class-
         --     wide conditions, where the conditions include calls to other
         --     overridden primitives. The wrappers include checks on these
         --     modified conditions. (AI12-113).

         --  5. Declarations built for subprograms without separate specs that
         --     are eligible for inlining in GNATprove (inside
         --     Sem_Ch6.Analyze_Subprogram_Body_Helper).

         if Present (Old_Subp)
           and then Present (Overridden_Operation (Subp))
           and then Is_Dispatching_Operation (Old_Subp)
         then
            pragma Assert
              ((Ekind (Subp) = E_Function
                 and then Is_Dispatching_Operation (Old_Subp)
                 and then Is_Null_Extension (Base_Type (Etype (Subp))))

              or else
               (Ekind (Subp) = E_Procedure
                 and then Is_Dispatching_Operation (Old_Subp)
                 and then Present (Alias (Old_Subp))
                 and then Is_Null_Interface_Primitive
                             (Ultimate_Alias (Old_Subp)))

              or else Get_TSS_Name (Subp) = TSS_Stream_Read
              or else Get_TSS_Name (Subp) = TSS_Stream_Write
              or else Get_TSS_Name (Subp) = TSS_Put_Image

              or else
               (Is_Wrapper (Subp)
                 and then Present (LSP_Subprogram (Subp)))

              or else GNATprove_Mode);

            Check_Controlling_Formals (Tagged_Type, Subp);
            Override_Dispatching_Operation (Tagged_Type, Old_Subp, Subp);
            Set_Is_Dispatching_Operation (Subp);
         end if;

         return;

      --  The operation may be a child unit, whose scope is the defining
      --  package, but which is not a primitive operation of the type.

      elsif Is_Child_Unit (Subp) then
         return;

      --  If the subprogram is not defined in a package spec, the only case
      --  where it can be a dispatching op is when it overrides an operation
      --  before the freezing point of the type.

      elsif ((not Is_Package_Or_Generic_Package (Scope (Subp)))
               or else In_Package_Body (Scope (Subp)))
        and then not Has_Dispatching_Parent
      then
         if not Comes_From_Source (Subp)
           or else (Present (Old_Subp) and then not Is_Frozen (Tagged_Type))
         then
            null;

         --  If the type is already frozen, the overriding is not allowed
         --  except when Old_Subp is not a dispatching operation (which can
         --  occur when Old_Subp was inherited by an untagged type). However,
         --  a body with no previous spec freezes the type *after* its
         --  declaration, and therefore is a legal overriding (unless the type
         --  has already been frozen). Only the first such body is legal.

         elsif Present (Old_Subp)
           and then Is_Dispatching_Operation (Old_Subp)
         then
            if Comes_From_Source (Subp)
              and then
                (Nkind (Unit_Declaration_Node (Subp)) = N_Subprogram_Body
                  or else Nkind (Unit_Declaration_Node (Subp)) in N_Body_Stub)
            then
               declare
                  Subp_Body : constant Node_Id := Unit_Declaration_Node (Subp);
                  Decl_Item : Node_Id;

               begin
                  --  ??? The checks here for whether the type has been frozen
                  --  prior to the new body are not complete. It's not simple
                  --  to check frozenness at this point since the body has
                  --  already caused the type to be prematurely frozen in
                  --  Analyze_Declarations, but we're forced to recheck this
                  --  here because of the odd rule interpretation that allows
                  --  the overriding if the type wasn't frozen prior to the
                  --  body. The freezing action should probably be delayed
                  --  until after the spec is seen, but that's a tricky
                  --  change to the delicate freezing code.

                  --  Look at each declaration following the type up until the
                  --  new subprogram body. If any of the declarations is a body
                  --  then the type has been frozen already so the overriding
                  --  primitive is illegal.

                  Decl_Item := Next (Parent (Tagged_Type));
                  while Present (Decl_Item)
                    and then (Decl_Item /= Subp_Body)
                  loop
                     if Comes_From_Source (Decl_Item)
                       and then (Nkind (Decl_Item) in N_Proper_Body
                                  or else Nkind (Decl_Item) in N_Body_Stub)
                     then
                        Error_Msg_N ("overriding of& is too late!", Subp);
                        Error_Msg_N
                          ("\spec should appear immediately after the type!",
                           Subp);
                        exit;
                     end if;

                     Next (Decl_Item);
                  end loop;

                  --  If the subprogram doesn't follow in the list of
                  --  declarations including the type then the type has
                  --  definitely been frozen already and the body is illegal.

                  if No (Decl_Item) then
                     Error_Msg_N ("overriding of& is too late!", Subp);
                     Error_Msg_N
                       ("\spec should appear immediately after the type!",
                        Subp);

                  elsif Is_Frozen (Subp) then

                     --  The subprogram body declares a primitive operation.
                     --  If the subprogram is already frozen, we must update
                     --  its dispatching information explicitly here. The
                     --  information is taken from the overridden subprogram.
                     --  We must also generate a cross-reference entry because
                     --  references to other primitives were already created
                     --  when type was frozen.

                     Body_Is_Last_Primitive := True;

                     if Present (DTC_Entity (Old_Subp)) then
                        Set_DTC_Entity (Subp, DTC_Entity (Old_Subp));
                        Set_DT_Position_Value (Subp, DT_Position (Old_Subp));

                        if not Restriction_Active (No_Dispatching_Calls) then
                           if Building_Static_DT (Tagged_Type) then

                              --  If the static dispatch table has not been
                              --  built then there is nothing else to do now;
                              --  otherwise we notify that we cannot build the
                              --  static dispatch table.

                              if Has_Dispatch_Table (Tagged_Type) then
                                 Error_Msg_N
                                   ("overriding of& is too late for building "
                                    & " static dispatch tables!", Subp);
                                 Error_Msg_N
                                   ("\spec should appear immediately after "
                                    & "the type!", Subp);
                              end if;

                           --  No code required to register primitives in VM
                           --  targets

                           elsif not Tagged_Type_Expansion then
                              null;

                           else
                              Insert_Actions_After (Subp_Body,
                                Register_Primitive (Sloc (Subp_Body),
                                Prim    => Subp));
                           end if;

                           --  Indicate that this is an overriding operation,
                           --  and replace the overridden entry in the list of
                           --  primitive operations, which is used for xref
                           --  generation subsequently.

                           Generate_Reference (Tagged_Type, Subp, 'P', False);
                           Override_Dispatching_Operation
                             (Tagged_Type, Old_Subp, Subp);
                           Set_Is_Dispatching_Operation (Subp);

                           --  Inherit decoration of controlling formals and
                           --  controlling result.

                           if Ekind (Old_Subp) = E_Function
                             and then Has_Controlling_Result (Old_Subp)
                           then
                              Set_Has_Controlling_Result (Subp);
                           end if;

                           if Present (First_Formal (Old_Subp)) then
                              declare
                                 Old_Formal : Entity_Id;
                                 Formal     : Entity_Id;

                              begin
                                 Formal     := First_Formal (Subp);
                                 Old_Formal := First_Formal (Old_Subp);

                                 while Present (Old_Formal) loop
                                    Set_Is_Controlling_Formal (Formal,
                                      Is_Controlling_Formal (Old_Formal));

                                    Next_Formal (Formal);
                                    Next_Formal (Old_Formal);
                                 end loop;
                              end;
                           end if;
                        end if;

                        Check_Inherited_Conditions (Tagged_Type,
                          Late_Overriding => True);
                     end if;
                  end if;
               end;

            else
               Error_Msg_N ("overriding of& is too late!", Subp);
               Error_Msg_N
                 ("\subprogram spec should appear immediately after the type!",
                  Subp);
            end if;

         --  If the type is not frozen yet and we are not in the overriding
         --  case it looks suspiciously like an attempt to define a primitive
         --  operation, which requires the declaration to be in a package spec
         --  (3.2.3(6)). Only report cases where the type and subprogram are
         --  in the same declaration list (by checking the enclosing parent
         --  declarations), to avoid spurious warnings on subprograms in
         --  instance bodies when the type is declared in the instance spec
         --  but hasn't been frozen by the instance body.

         elsif not Is_Frozen (Tagged_Type)
           and then In_Same_List (Parent (Tagged_Type), Parent (Parent (Subp)))
         then
            Error_Msg_N
              ("??not dispatching (must be defined in a package spec)", Subp);
            return;

         --  When the type is frozen, it is legitimate to define a new
         --  non-primitive operation.

         else
            return;
         end if;

      --  Now, we are sure that the scope is a package spec. If the subprogram
      --  is declared after the freezing point of the type that's an error

      elsif Is_Frozen (Tagged_Type) and then not Has_Dispatching_Parent then
         Error_Msg_N ("this primitive operation is declared too late", Subp);
         Error_Msg_NE
           ("??no primitive operations for& after this line",
            Freeze_Node (Tagged_Type),
            Tagged_Type);
         return;
      end if;

      Check_Controlling_Formals (Tagged_Type, Subp);

      Ovr_Subp := Old_Subp;

      --  [Ada 2012:AI-0125]: Search for inherited hidden primitive that may be
      --  overridden by Subp. This only applies to source subprograms, and
      --  their declaration must carry an explicit overriding indicator.

      if No (Ovr_Subp)
        and then Ada_Version >= Ada_2012
        and then Comes_From_Source (Subp)
        and then
          Nkind (Unit_Declaration_Node (Subp)) = N_Subprogram_Declaration
      then
         Ovr_Subp := Find_Hidden_Overridden_Primitive (Subp);

         --  Verify that the proper overriding indicator has been supplied.

         if Present (Ovr_Subp)
           and then
             not Must_Override (Specification (Unit_Declaration_Node (Subp)))
         then
            Error_Msg_NE ("missing overriding indicator for&", Subp, Subp);
         end if;
      end if;

      --  Now it should be a correct primitive operation, put it in the list

      if Present (Ovr_Subp) then

         --  If the type has interfaces we complete this check after we set
         --  attribute Is_Dispatching_Operation.

         Check_Subtype_Conformant (Subp, Ovr_Subp);

         --  A primitive operation with the name of a primitive controlled
         --  operation does not override a non-visible overriding controlled
         --  operation, i.e. one declared in a private part when the full
         --  view of a type is controlled. Conversely, it will override a
         --  visible operation that may be declared in a partial view when
         --  the full view is controlled.

         if Chars (Subp) in Name_Initialize | Name_Adjust | Name_Finalize
           and then Is_Controlled (Tagged_Type)
           and then not Is_Visibly_Controlled (Tagged_Type)
           and then not Is_Inherited_Public_Operation (Ovr_Subp)
         then
            Set_Overridden_Operation (Subp, Empty);

            --  If the subprogram specification carries an overriding
            --  indicator, no need for the warning: it is either redundant,
            --  or else an error will be reported.

            if Nkind (Parent (Subp)) = N_Procedure_Specification
              and then
                (Must_Override (Parent (Subp))
                  or else Must_Not_Override (Parent (Subp)))
            then
               null;

            --  Here we need the warning

            else
               Error_Msg_NE
                 ("operation does not override inherited&??", Subp, Subp);
            end if;

         else
            Override_Dispatching_Operation (Tagged_Type, Ovr_Subp, Subp);

            --  Ada 2005 (AI-251): In case of late overriding of a primitive
            --  that covers abstract interface subprograms we must register it
            --  in all the secondary dispatch tables associated with abstract
            --  interfaces. We do this now only if not building static tables,
            --  nor when the expander is inactive (we avoid trying to register
            --  primitives in semantics-only mode, since the type may not have
            --  an associated dispatch table). Otherwise the patch code is
            --  emitted after those tables are built, to prevent access before
            --  elaboration in gigi.

            if Body_Is_Last_Primitive and then Expander_Active then
               declare
                  Subp_Body : constant Node_Id := Unit_Declaration_Node (Subp);
                  Elmt      : Elmt_Id;
                  Prim      : Node_Id;

               begin
                  Elmt := First_Elmt (Primitive_Operations (Tagged_Type));
                  while Present (Elmt) loop
                     Prim := Node (Elmt);

                     --  No code required to register primitives in VM targets

                     if Present (Alias (Prim))
                       and then Present (Interface_Alias (Prim))
                       and then Alias (Prim) = Subp
                       and then not Building_Static_DT (Tagged_Type)
                       and then Tagged_Type_Expansion
                     then
                        Insert_Actions_After (Subp_Body,
                          Register_Primitive (Sloc (Subp_Body), Prim => Prim));
                     end if;

                     Next_Elmt (Elmt);
                  end loop;

                  --  Redisplay the contents of the updated dispatch table

                  if Debug_Flag_ZZ then
                     Write_Str ("Late overriding: ");
                     Write_DT (Tagged_Type);
                  end if;
               end;
            end if;
         end if;

      --  If no old subprogram, then we add this as a dispatching operation,
      --  but we avoid doing this if an error was posted, to prevent annoying
      --  cascaded errors.

      elsif not Error_Posted (Subp) then
         Add_Dispatching_Operation (Tagged_Type, Subp);
      end if;

      Set_Is_Dispatching_Operation (Subp, True);

      --  Ada 2005 (AI-251): If the type implements interfaces we must check
      --  subtype conformance against all the interfaces covered by this
      --  primitive.

      if Present (Ovr_Subp)
        and then Has_Interfaces (Tagged_Type)
      then
         declare
            Ifaces_List     : Elist_Id;
            Iface_Elmt      : Elmt_Id;
            Iface_Prim_Elmt : Elmt_Id;
            Iface_Prim      : Entity_Id;
            Ret_Typ         : Entity_Id;

         begin
            Collect_Interfaces (Tagged_Type, Ifaces_List);

            Iface_Elmt := First_Elmt (Ifaces_List);
            while Present (Iface_Elmt) loop
               if not Is_Ancestor (Node (Iface_Elmt), Tagged_Type) then
                  Iface_Prim_Elmt :=
                    First_Elmt (Primitive_Operations (Node (Iface_Elmt)));
                  while Present (Iface_Prim_Elmt) loop
                     Iface_Prim := Node (Iface_Prim_Elmt);

                     if Is_Interface_Conformant
                          (Tagged_Type, Iface_Prim, Subp)
                     then
                        --  Handle procedures, functions whose return type
                        --  matches, or functions not returning interfaces

                        if Ekind (Subp) = E_Procedure
                          or else Etype (Iface_Prim) = Etype (Subp)
                          or else not Is_Interface (Etype (Iface_Prim))
                        then
                           Check_Subtype_Conformant
                             (New_Id  => Subp,
                              Old_Id  => Iface_Prim,
                              Err_Loc => Subp,
                              Skip_Controlling_Formals => True);

                        --  Handle functions returning interfaces

                        elsif Implements_Interface
                                (Etype (Subp), Etype (Iface_Prim))
                        then
                           --  Temporarily force both entities to return the
                           --  same type. Required because Subtype_Conformant
                           --  does not handle this case.

                           Ret_Typ := Etype (Iface_Prim);
                           Set_Etype (Iface_Prim, Etype (Subp));

                           Check_Subtype_Conformant
                             (New_Id  => Subp,
                              Old_Id  => Iface_Prim,
                              Err_Loc => Subp,
                              Skip_Controlling_Formals => True);

                           Set_Etype (Iface_Prim, Ret_Typ);
                        end if;
                     end if;

                     Next_Elmt (Iface_Prim_Elmt);
                  end loop;
               end if;

               Next_Elmt (Iface_Elmt);
            end loop;
         end;
      end if;

      if not Body_Is_Last_Primitive then
         Set_DT_Position_Value (Subp, No_Uint);

      elsif Has_Controlled_Component (Tagged_Type)
        and then Chars (Subp) in Name_Initialize
                               | Name_Adjust
                               | Name_Finalize
                               | Name_Finalize_Address
      then
         declare
            F_Node   : constant Node_Id := Freeze_Node (Tagged_Type);
            Decl     : Node_Id;
            Old_P    : Entity_Id;
            Old_Bod  : Node_Id;
            Old_Spec : Entity_Id;

            C_Names : constant array (1 .. 4) of Name_Id :=
                        (Name_Initialize,
                         Name_Adjust,
                         Name_Finalize,
                         Name_Finalize_Address);

            D_Names : constant array (1 .. 4) of TSS_Name_Type :=
                        (TSS_Deep_Initialize,
                         TSS_Deep_Adjust,
                         TSS_Deep_Finalize,
                         TSS_Finalize_Address);

         begin
            --  Remove previous controlled function which was constructed and
            --  analyzed when the type was frozen. This requires removing the
            --  body of the redefined primitive, as well as its specification
            --  if needed (there is no spec created for Deep_Initialize, see
            --  exp_ch3.adb). We must also dismantle the exception information
            --  that may have been generated for it when front end zero-cost
            --  tables are enabled.

            for J in D_Names'Range loop
               Old_P := TSS (Tagged_Type, D_Names (J));

               if Present (Old_P)
                and then Chars (Subp) = C_Names (J)
               then
                  Old_Bod := Unit_Declaration_Node (Old_P);
                  Remove (Old_Bod);
                  Set_Is_Eliminated (Old_P);
                  Set_Scope (Old_P,  Scope (Current_Scope));

                  if Nkind (Old_Bod) = N_Subprogram_Body
                    and then Present (Corresponding_Spec (Old_Bod))
                  then
                     Old_Spec := Corresponding_Spec (Old_Bod);
                     Set_Has_Completion             (Old_Spec, False);
                  end if;
               end if;
            end loop;

            Build_Late_Proc (Tagged_Type, Chars (Subp));

            --  The new operation is added to the actions of the freeze node
            --  for the type, but this node has already been analyzed, so we
            --  must retrieve and analyze explicitly the new body.

            if Present (F_Node)
              and then Present (Actions (F_Node))
            then
               Decl := Last (Actions (F_Node));
               Analyze (Decl);
            end if;
         end;
      end if;

      --  AI12-0279: If the Yield aspect is specified for a dispatching
      --  subprogram that inherits the aspect, the specified value shall
      --  be confirming.

      if Is_Dispatching_Operation (Subp)
        and then Is_Primitive_Wrapper (Subp)
        and then Present (Wrapped_Entity (Subp))
        and then Comes_From_Source (Wrapped_Entity (Subp))
        and then Present (Overridden_Operation (Subp))
        and then Has_Yield_Aspect (Overridden_Operation (Subp))
                   /= Has_Yield_Aspect (Wrapped_Entity (Subp))
      then
         declare
            W_Ent  : constant Entity_Id := Wrapped_Entity (Subp);
            W_Decl : constant Node_Id := Parent (W_Ent);
            Asp    : Node_Id;

         begin
            if Present (Aspect_Specifications (W_Decl)) then
               Asp := First (Aspect_Specifications (W_Decl));
               while Present (Asp) loop
                  if Chars (Identifier (Asp)) = Name_Yield then
                     Error_Msg_Name_1 := Name_Yield;
                     Error_Msg_N
                       ("specification of inherited aspect% can only confirm "
                        & "parent value", Asp);
                  end if;

                  Next (Asp);
               end loop;
            end if;

            Set_Has_Yield_Aspect (Wrapped_Entity (Subp));
         end;
      end if;

      --  For similarity with record extensions, in Ada 9X the language should
      --  have disallowed adding visible operations to a tagged type after
      --  deriving a private extension from it. Report a warning if this
      --  primitive is defined after a private extension of Tagged_Type.

      Warn_On_Late_Primitive_After_Private_Extension (Tagged_Type, Subp);
   end Check_Dispatching_Operation;

   ------------------------------------------
   -- Check_Operation_From_Incomplete_Type --
   ------------------------------------------

   procedure Check_Operation_From_Incomplete_Type
     (Subp : Entity_Id;
      Typ  : Entity_Id)
   is
      Full       : constant Entity_Id := Full_View (Typ);
      Parent_Typ : constant Entity_Id := Etype (Full);
      Old_Prim   : constant Elist_Id  := Primitive_Operations (Parent_Typ);
      New_Prim   : constant Elist_Id  := Primitive_Operations (Full);
      Op1, Op2   : Elmt_Id;
      Prev       : Elmt_Id := No_Elmt;

      function Derives_From (Parent_Subp : Entity_Id) return Boolean;
      --  Check that Subp has profile of an operation derived from Parent_Subp.
      --  Subp must have a parameter or result type that is Typ or an access
      --  parameter or access result type that designates Typ.

      ------------------
      -- Derives_From --
      ------------------

      function Derives_From (Parent_Subp : Entity_Id) return Boolean is
         F1, F2 : Entity_Id;

      begin
         if Chars (Parent_Subp) /= Chars (Subp) then
            return False;
         end if;

         --  Check that the type of controlling formals is derived from the
         --  parent subprogram's controlling formal type (or designated type
         --  if the formal type is an anonymous access type).

         F1 := First_Formal (Parent_Subp);
         F2 := First_Formal (Subp);
         while Present (F1) and then Present (F2) loop
            if Ekind (Etype (F1)) = E_Anonymous_Access_Type then
               if Ekind (Etype (F2)) /= E_Anonymous_Access_Type then
                  return False;
               elsif Designated_Type (Etype (F1)) = Parent_Typ
                 and then Designated_Type (Etype (F2)) /= Full
               then
                  return False;
               end if;

            elsif Ekind (Etype (F2)) = E_Anonymous_Access_Type then
               return False;

            elsif Etype (F1) = Parent_Typ and then Etype (F2) /= Full then
               return False;
            end if;

            Next_Formal (F1);
            Next_Formal (F2);
         end loop;

         --  Check that a controlling result type is derived from the parent
         --  subprogram's result type (or designated type if the result type
         --  is an anonymous access type).

         if Ekind (Parent_Subp) = E_Function then
            if Ekind (Subp) /= E_Function then
               return False;

            elsif Ekind (Etype (Parent_Subp)) = E_Anonymous_Access_Type then
               if Ekind (Etype (Subp)) /= E_Anonymous_Access_Type then
                  return False;

               elsif Designated_Type (Etype (Parent_Subp)) = Parent_Typ
                 and then Designated_Type (Etype (Subp)) /= Full
               then
                  return False;
               end if;

            elsif Ekind (Etype (Subp)) = E_Anonymous_Access_Type then
               return False;

            elsif Etype (Parent_Subp) = Parent_Typ
              and then Etype (Subp) /= Full
            then
               return False;
            end if;

         elsif Ekind (Subp) = E_Function then
            return False;
         end if;

         return No (F1) and then No (F2);
      end Derives_From;

   --  Start of processing for Check_Operation_From_Incomplete_Type

   begin
      --  The operation may override an inherited one, or may be a new one
      --  altogether. The inherited operation will have been hidden by the
      --  current one at the point of the type derivation, so it does not
      --  appear in the list of primitive operations of the type. We have to
      --  find the proper place of insertion in the list of primitive opera-
      --  tions by iterating over the list for the parent type.

      Op1 := First_Elmt (Old_Prim);
      Op2 := First_Elmt (New_Prim);
      while Present (Op1) and then Present (Op2) loop
         if Derives_From (Node (Op1)) then
            if No (Prev) then

               --  Avoid adding it to the list of primitives if already there

               if Node (Op2) /= Subp then
                  Prepend_Elmt (Subp, New_Prim);
               end if;

            else
               Insert_Elmt_After (Subp, Prev);
            end if;

            return;
         end if;

         Prev := Op2;
         Next_Elmt (Op1);
         Next_Elmt (Op2);
      end loop;

      --  Operation is a new primitive

      Append_Elmt (Subp, New_Prim);
   end Check_Operation_From_Incomplete_Type;

   ---------------------------------------
   -- Check_Operation_From_Private_View --
   ---------------------------------------

   procedure Check_Operation_From_Private_View (Subp, Old_Subp : Entity_Id) is
      Tagged_Type : Entity_Id;

   begin
      if Is_Dispatching_Operation (Alias (Subp)) then
         Set_Scope (Subp, Current_Scope);
         Tagged_Type := Find_Dispatching_Type (Subp);

         --  Add Old_Subp to primitive operations if not already present

         if Present (Tagged_Type) and then Is_Tagged_Type (Tagged_Type) then
            Add_Dispatching_Operation (Tagged_Type, Old_Subp);

            --  If Old_Subp isn't already marked as dispatching then this is
            --  the case of an operation of an untagged private type fulfilled
            --  by a tagged type that overrides an inherited dispatching
            --  operation, so we set the necessary dispatching attributes here.

            if not Is_Dispatching_Operation (Old_Subp) then

               --  If the untagged type has no discriminants, and the full
               --  view is constrained, there will be a spurious mismatch of
               --  subtypes on the controlling arguments, because the tagged
               --  type is the internal base type introduced in the derivation.
               --  Use the original type to verify conformance, rather than the
               --  base type.

               if not Comes_From_Source (Tagged_Type)
                 and then Has_Discriminants (Tagged_Type)
               then
                  declare
                     Formal : Entity_Id;

                  begin
                     Formal := First_Formal (Old_Subp);
                     while Present (Formal) loop
                        if Tagged_Type = Base_Type (Etype (Formal)) then
                           Tagged_Type := Etype (Formal);
                        end if;

                        Next_Formal (Formal);
                     end loop;
                  end;

                  if Tagged_Type = Base_Type (Etype (Old_Subp)) then
                     Tagged_Type := Etype (Old_Subp);
                  end if;
               end if;

               Check_Controlling_Formals (Tagged_Type, Old_Subp);
               Set_Is_Dispatching_Operation (Old_Subp, True);
               Set_DT_Position_Value (Old_Subp, No_Uint);
            end if;

            --  If the old subprogram is an explicit renaming of some other
            --  entity, it is not overridden by the inherited subprogram.
            --  Otherwise, update its alias and other attributes.

            if Present (Alias (Old_Subp))
              and then Nkind (Unit_Declaration_Node (Old_Subp)) /=
                                        N_Subprogram_Renaming_Declaration
            then
               Set_Alias (Old_Subp, Alias (Subp));

               --  The derived subprogram should inherit the abstractness of
               --  the parent subprogram (except in the case of a function
               --  returning the type). This sets the abstractness properly
               --  for cases where a private extension may have inherited an
               --  abstract operation, but the full type is derived from a
               --  descendant type and inherits a nonabstract version.

               if Etype (Subp) /= Tagged_Type then
                  Set_Is_Abstract_Subprogram
                    (Old_Subp, Is_Abstract_Subprogram (Alias (Subp)));
               end if;
            end if;
         end if;
      end if;
   end Check_Operation_From_Private_View;

   --------------------------
   -- Find_Controlling_Arg --
   --------------------------

   function Find_Controlling_Arg (N : Node_Id) return Node_Id is
      Orig_Node : constant Node_Id := Original_Node (N);
      Typ       : Entity_Id;

   begin
      if Nkind (Orig_Node) = N_Qualified_Expression then
         return Find_Controlling_Arg (Expression (Orig_Node));
      end if;

      --  Dispatching on result case. If expansion is disabled, the node still
      --  has the structure of a function call. However, if the function name
      --  is an operator and the call was given in infix form, the original
      --  node has no controlling result and we must examine the current node.

      if Nkind (N) = N_Function_Call
        and then Present (Controlling_Argument (N))
        and then Has_Controlling_Result (Entity (Name (N)))
      then
         return Controlling_Argument (N);

      --  If expansion is enabled, the call may have been transformed into
      --  an indirect call, and we need to recover the original node.

      elsif Nkind (Orig_Node) = N_Function_Call
        and then Present (Controlling_Argument (Orig_Node))
        and then Has_Controlling_Result (Entity (Name (Orig_Node)))
      then
         return Controlling_Argument (Orig_Node);

      --  Type conversions are dynamically tagged if the target type, or its
      --  designated type, are classwide. An interface conversion expands into
      --  a dereference, so test must be performed on the original node.

      elsif Nkind (Orig_Node) = N_Type_Conversion
        and then Nkind (N) = N_Explicit_Dereference
        and then Is_Controlling_Actual (N)
      then
         declare
            Target_Type : constant Entity_Id :=
                             Entity (Subtype_Mark (Orig_Node));

         begin
            if Is_Class_Wide_Type (Target_Type) then
               return N;

            elsif Is_Access_Type (Target_Type)
              and then Is_Class_Wide_Type (Designated_Type (Target_Type))
            then
               return N;

            else
               return Empty;
            end if;
         end;

      --  Normal case

      elsif Is_Controlling_Actual (N)
        or else
         (Nkind (Parent (N)) = N_Qualified_Expression
           and then Is_Controlling_Actual (Parent (N)))
      then
         Typ := Etype (N);

         if Is_Access_Type (Typ) then

            --  In the case of an Access attribute, use the type of the prefix,
            --  since in the case of an actual for an access parameter, the
            --  attribute's type may be of a specific designated type, even
            --  though the prefix type is class-wide.

            if Nkind (N) = N_Attribute_Reference then
               Typ := Etype (Prefix (N));

            --  An allocator is dispatching if the type of qualified expression
            --  is class_wide, in which case this is the controlling type.

            elsif Nkind (Orig_Node) = N_Allocator
               and then Nkind (Expression (Orig_Node)) = N_Qualified_Expression
            then
               Typ := Etype (Expression (Orig_Node));
            else
               Typ := Designated_Type (Typ);
            end if;
         end if;

         if Is_Class_Wide_Type (Typ)
           or else
             (Nkind (Parent (N)) = N_Qualified_Expression
               and then Is_Access_Type (Etype (N))
               and then Is_Class_Wide_Type (Designated_Type (Etype (N))))
         then
            return N;
         end if;
      end if;

      return Empty;
   end Find_Controlling_Arg;

   ---------------------------
   -- Find_Dispatching_Type --
   ---------------------------

   function Find_Dispatching_Type (Subp : Entity_Id) return Entity_Id is
      A_Formal  : Entity_Id;
      Formal    : Entity_Id;
      Ctrl_Type : Entity_Id;

   begin
      if Ekind (Subp) in E_Function | E_Procedure
        and then Present (DTC_Entity (Subp))
      then
         return Scope (DTC_Entity (Subp));

      --  For subprograms internally generated by derivations of tagged types
      --  use the alias subprogram as a reference to locate the dispatching
      --  type of Subp.

      elsif not Comes_From_Source (Subp)
        and then Present (Alias (Subp))
        and then Is_Dispatching_Operation (Alias (Subp))
      then
         if Ekind (Alias (Subp)) = E_Function
           and then Has_Controlling_Result (Alias (Subp))
         then
            return Check_Controlling_Type (Etype (Subp), Subp);

         else
            Formal   := First_Formal (Subp);
            A_Formal := First_Formal (Alias (Subp));
            while Present (A_Formal) loop
               if Is_Controlling_Formal (A_Formal) then
                  return Check_Controlling_Type (Etype (Formal), Subp);
               end if;

               Next_Formal (Formal);
               Next_Formal (A_Formal);
            end loop;

            pragma Assert (False);
            return Empty;
         end if;

      --  General case

      else
         Formal := First_Formal (Subp);
         while Present (Formal) loop
            Ctrl_Type := Check_Controlling_Type (Etype (Formal), Subp);

            if Present (Ctrl_Type) then
               return Ctrl_Type;
            end if;

            Next_Formal (Formal);
         end loop;

         --  The subprogram may also be dispatching on result

         if Present (Etype (Subp)) then
            return Check_Controlling_Type (Etype (Subp), Subp);
         end if;
      end if;

      pragma Assert (not Is_Dispatching_Operation (Subp));
      return Empty;
   end Find_Dispatching_Type;

   --------------------------------------
   -- Find_Hidden_Overridden_Primitive --
   --------------------------------------

   function Find_Hidden_Overridden_Primitive (S : Entity_Id) return Entity_Id
   is
      Tag_Typ   : constant Entity_Id := Find_Dispatching_Type (S);
      Elmt      : Elmt_Id;
      Orig_Prim : Entity_Id;
      Prim      : Entity_Id;
      Vis_List  : Elist_Id;

   begin
      --  This Ada 2012 rule applies only for type extensions or private
      --  extensions, where the parent type is not in a parent unit, and
      --  where an operation is never declared but still inherited.

      if No (Tag_Typ)
        or else not Is_Record_Type (Tag_Typ)
        or else Etype (Tag_Typ) = Tag_Typ
        or else In_Open_Scopes (Scope (Etype (Tag_Typ)))
      then
         return Empty;
      end if;

      --  Collect the list of visible ancestor of the tagged type

      Vis_List := Visible_Ancestors (Tag_Typ);

      Elmt := First_Elmt (Primitive_Operations (Tag_Typ));
      while Present (Elmt) loop
         Prim := Node (Elmt);

         --  Find an inherited hidden dispatching primitive with the name of S
         --  and a type-conformant profile.

         if Present (Alias (Prim))
           and then Is_Hidden (Alias (Prim))
           and then Find_Dispatching_Type (Alias (Prim)) /= Tag_Typ
           and then Primitive_Names_Match (S, Prim)
           and then Type_Conformant (S, Prim)
         then
            declare
               Vis_Ancestor : Elmt_Id;
               Elmt         : Elmt_Id;

            begin
               --  The original corresponding operation of Prim must be an
               --  operation of a visible ancestor of the dispatching type S,
               --  and the original corresponding operation of S2 must be
               --  visible.

               Orig_Prim := Original_Corresponding_Operation (Prim);

               if Orig_Prim /= Prim
                 and then Is_Immediately_Visible (Orig_Prim)
               then
                  Vis_Ancestor := First_Elmt (Vis_List);
                  while Present (Vis_Ancestor) loop
                     Elmt :=
                       First_Elmt (Primitive_Operations (Node (Vis_Ancestor)));
                     while Present (Elmt) loop
                        if Node (Elmt) = Orig_Prim then
                           Set_Overridden_Operation (S, Prim);
                           Set_Is_Ada_2022_Only     (S,
                             Is_Ada_2022_Only (Prim));
                           Set_Alias (Prim, Orig_Prim);
                           return Prim;
                        end if;

                        Next_Elmt (Elmt);
                     end loop;

                     Next_Elmt (Vis_Ancestor);
                  end loop;
               end if;
            end;
         end if;

         Next_Elmt (Elmt);
      end loop;

      return Empty;
   end Find_Hidden_Overridden_Primitive;

   ---------------------------------------
   -- Find_Primitive_Covering_Interface --
   ---------------------------------------

   function Find_Primitive_Covering_Interface
     (Tagged_Type : Entity_Id;
      Iface_Prim  : Entity_Id) return Entity_Id
   is
      E  : Entity_Id;
      El : Elmt_Id;

   begin
      pragma Assert (Is_Interface (Find_Dispatching_Type (Iface_Prim))
        or else (Present (Alias (Iface_Prim))
                  and then
                    Is_Interface
                      (Find_Dispatching_Type (Ultimate_Alias (Iface_Prim)))));

      --  Search in the homonym chain. Done to speed up locating visible
      --  entities and required to catch primitives associated with the partial
      --  view of private types when processing the corresponding full view.

      E := Current_Entity (Iface_Prim);
      while Present (E) loop
         if Is_Subprogram (E)
           and then Is_Dispatching_Operation (E)
           and then Is_Interface_Conformant (Tagged_Type, Iface_Prim, E)
         then
            return E;
         end if;

         E := Homonym (E);
      end loop;

      --  Search in the list of primitives of the type. Required to locate
      --  the covering primitive if the covering primitive is not visible
      --  (for example, non-visible inherited primitive of private type).

      El := First_Elmt (Primitive_Operations (Tagged_Type));
      while Present (El) loop
         E := Node (El);

         --  Keep separate the management of internal entities that link
         --  primitives with interface primitives from tagged type primitives.

         if No (Interface_Alias (E)) then
            if Present (Alias (E)) then

               --  This interface primitive has not been covered yet

               if Alias (E) = Iface_Prim then
                  return E;

               --  The covering primitive was inherited

               elsif Overridden_Operation (Ultimate_Alias (E))
                       = Iface_Prim
               then
                  return E;
               end if;
            end if;

            --  Check if E covers the interface primitive (includes case in
            --  which E is an inherited private primitive).

            if Is_Interface_Conformant (Tagged_Type, Iface_Prim, E) then
               return E;
            end if;

         --  Use the internal entity that links the interface primitive with
         --  the covering primitive to locate the entity.

         elsif Interface_Alias (E) = Iface_Prim then
            return Alias (E);
         end if;

         Next_Elmt (El);
      end loop;

      --  Not found

      return Empty;
   end Find_Primitive_Covering_Interface;

   ---------------------------
   -- Inheritance_Utilities --
   ---------------------------

   package body Inheritance_Utilities is

      ---------------------------
      -- Inherited_Subprograms --
      ---------------------------

      function Inherited_Subprograms
        (S               : Entity_Id;
         No_Interfaces   : Boolean := False;
         Interfaces_Only : Boolean := False;
         One_Only        : Boolean := False) return Subprogram_List
      is
         Result : Subprogram_List (1 .. 6000);
         --  6000 here is intended to be infinity. We could use an expandable
         --  table, but it would be awfully heavy, and there is no way that we
         --  could reasonably exceed this value.

         N : Nat := 0;
         --  Number of entries in Result

         Parent_Op : Entity_Id;
         --  Traverses the Overridden_Operation chain

         procedure Store_IS (E : Entity_Id);
         --  Stores E in Result if not already stored

         --------------
         -- Store_IS --
         --------------

         procedure Store_IS (E : Entity_Id) is
         begin
            for J in 1 .. N loop
               if E = Result (J) then
                  return;
               end if;
            end loop;

            N := N + 1;
            Result (N) := E;
         end Store_IS;

      --  Start of processing for Inherited_Subprograms

      begin
         pragma Assert (not (No_Interfaces and Interfaces_Only));

         --  When used from backends, visibility can be handled differently
         --  resulting in no dispatching type being found.

         if Present (S)
           and then Is_Dispatching_Operation (S)
           and then Present (Find_DT (S))
         then
            --  Deal with direct inheritance

            if not Interfaces_Only then
               Parent_Op := S;
               loop
                  Parent_Op := Overridden_Operation (Parent_Op);
                  exit when No (Parent_Op)
                    or else (No_Interfaces
                              and then Is_Interface (Find_DT (Parent_Op)));

                  if Is_Subprogram_Or_Generic_Subprogram (Parent_Op) then
                     Store_IS (Parent_Op);

                     if One_Only then
                        goto Done;
                     end if;
                  end if;
               end loop;
            end if;

            --  Now deal with interfaces

            if not No_Interfaces then
               declare
                  Tag_Typ : Entity_Id;
                  Prim    : Entity_Id;
                  Elmt    : Elmt_Id;

               begin
                  Tag_Typ := Find_DT (S);

                  --  In the presence of limited views there may be no visible
                  --  dispatching type. Primitives will be inherited when non-
                  --  limited view is frozen.

                  if No (Tag_Typ) then
                     return Result (1 .. 0);

                  --  Prevent cascaded errors

                  elsif Is_Concurrent_Type (Tag_Typ)
                     and then No (Corresponding_Record_Type (Tag_Typ))
                     and then Serious_Errors_Detected > 0
                  then
                     return Result (1 .. 0);
                  end if;

                  if Is_Concurrent_Type (Tag_Typ) then
                     Tag_Typ := Corresponding_Record_Type (Tag_Typ);
                  end if;

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

                  --  Search primitive operations of dispatching type

                  if Present (Tag_Typ)
                    and then Present (Primitive_Operations (Tag_Typ))
                  then
                     Elmt := First_Elmt (Primitive_Operations (Tag_Typ));
                     while Present (Elmt) loop
                        Prim := Node (Elmt);

                        --  The following test eliminates some odd cases in
                        --  which Ekind (Prim) is Void, to be investigated
                        --  further ???

                        if not Is_Subprogram_Or_Generic_Subprogram (Prim) then
                           null;

                           --  For [generic] subprogram, look at interface
                           --  alias.

                        elsif Present (Interface_Alias (Prim))
                          and then Alias (Prim) = S
                        then
                           --  We have found a primitive covered by S

                           Store_IS (Interface_Alias (Prim));

                           if One_Only then
                              goto Done;
                           end if;
                        end if;

                        Next_Elmt (Elmt);
                     end loop;
                  end if;
               end;
            end if;
         end if;

         <<Done>>

         return Result (1 .. N);
      end Inherited_Subprograms;

      ------------------------------
      -- Is_Overriding_Subprogram --
      ------------------------------

      function Is_Overriding_Subprogram (E : Entity_Id) return Boolean is
         Inherited : constant Subprogram_List :=
           Inherited_Subprograms (E, One_Only => True);
      begin
         return Inherited'Length > 0;
      end Is_Overriding_Subprogram;
   end Inheritance_Utilities;

   --------------------------------
   -- Inheritance_Utilities_Inst --
   --------------------------------

   package Inheritance_Utilities_Inst is new
     Inheritance_Utilities (Find_Dispatching_Type);

   ---------------------------
   -- Inherited_Subprograms --
   ---------------------------

   function Inherited_Subprograms
     (S               : Entity_Id;
      No_Interfaces   : Boolean := False;
      Interfaces_Only : Boolean := False;
      One_Only        : Boolean := False) return Subprogram_List renames
     Inheritance_Utilities_Inst.Inherited_Subprograms;

   ---------------------------
   -- Is_Dynamically_Tagged --
   ---------------------------

   function Is_Dynamically_Tagged (N : Node_Id) return Boolean is
   begin
      if Nkind (N) = N_Error then
         return False;

      elsif Present (Find_Controlling_Arg (N)) then
         return True;

      --  Special cases: entities, and calls that dispatch on result

      elsif Is_Entity_Name (N) then
         return Is_Class_Wide_Type (Etype (N));

      elsif Nkind (N) = N_Function_Call
         and then Is_Class_Wide_Type (Etype (N))
      then
         return True;

      --  Otherwise check whether call has controlling argument

      else
         return False;
      end if;
   end Is_Dynamically_Tagged;

   ---------------------------------
   -- Is_Null_Interface_Primitive --
   ---------------------------------

   function Is_Null_Interface_Primitive (E : Entity_Id) return Boolean is
   begin
      return Comes_From_Source (E)
        and then Is_Dispatching_Operation (E)
        and then Ekind (E) = E_Procedure
        and then Null_Present (Parent (E))
        and then Is_Interface (Find_Dispatching_Type (E));
   end Is_Null_Interface_Primitive;

   -----------------------------------
   -- Is_Inherited_Public_Operation --
   -----------------------------------

   function Is_Inherited_Public_Operation (Op : Entity_Id) return Boolean is
      Pack_Decl : Node_Id;
      Prim      : Entity_Id := Op;
      Scop      : Entity_Id := Prim;

   begin
      --  Locate the ultimate non-hidden alias entity

      while Present (Alias (Prim)) and then not Is_Hidden (Alias (Prim)) loop
         pragma Assert (Alias (Prim) /= Prim);
         Prim := Alias (Prim);
         Scop := Scope (Prim);
      end loop;

      if Comes_From_Source (Prim) and then Ekind (Scop) = E_Package then
         Pack_Decl := Unit_Declaration_Node (Scop);

         return
           Nkind (Pack_Decl) = N_Package_Declaration
             and then List_Containing (Unit_Declaration_Node (Prim)) =
                        Visible_Declarations (Specification (Pack_Decl));

      else
         return False;
      end if;
   end Is_Inherited_Public_Operation;

   ------------------------------
   -- Is_Overriding_Subprogram --
   ------------------------------

   function Is_Overriding_Subprogram (E : Entity_Id) return Boolean renames
     Inheritance_Utilities_Inst.Is_Overriding_Subprogram;

   --------------------------
   -- Is_Tag_Indeterminate --
   --------------------------

   function Is_Tag_Indeterminate (N : Node_Id) return Boolean is
      Nam       : Entity_Id;
      Actual    : Node_Id;
      Orig_Node : constant Node_Id := Original_Node (N);

   begin
      if Nkind (Orig_Node) = N_Function_Call
        and then Is_Entity_Name (Name (Orig_Node))
      then
         Nam := Entity (Name (Orig_Node));

         if not Has_Controlling_Result (Nam) then
            return False;

         --  The function may have a controlling result, but if the return type
         --  is not visibly tagged, then this is not tag-indeterminate.

         elsif Is_Access_Type (Etype (Nam))
           and then not Is_Tagged_Type (Designated_Type (Etype (Nam)))
         then
            return False;

         --  An explicit dereference means that the call has already been
         --  expanded and there is no tag to propagate.

         elsif Nkind (N) = N_Explicit_Dereference then
            return False;

         --  If there are no actuals, the call is tag-indeterminate

         elsif No (Parameter_Associations (Orig_Node)) then
            return True;

         else
            Actual := First_Actual (Orig_Node);
            while Present (Actual) loop
               if Is_Controlling_Actual (Actual)
                 and then not Is_Tag_Indeterminate (Actual)
               then
                  --  One operand is dispatching

                  return False;
               end if;

               Next_Actual (Actual);
            end loop;

            return True;
         end if;

      elsif Nkind (Orig_Node) = N_Qualified_Expression then
         return Is_Tag_Indeterminate (Expression (Orig_Node));

      --  Case of a call to the Input attribute (possibly rewritten), which is
      --  always tag-indeterminate except when its prefix is a Class attribute.

      elsif Nkind (Orig_Node) = N_Attribute_Reference
        and then
          Get_Attribute_Id (Attribute_Name (Orig_Node)) = Attribute_Input
        and then Nkind (Prefix (Orig_Node)) /= N_Attribute_Reference
      then
         return True;

      --  In Ada 2005, a function that returns an anonymous access type can be
      --  dispatching, and the dereference of a call to such a function can
      --  also be tag-indeterminate if the call itself is.

      elsif Nkind (Orig_Node) = N_Explicit_Dereference
        and then Ada_Version >= Ada_2005
      then
         return Is_Tag_Indeterminate (Prefix (Orig_Node));

      else
         return False;
      end if;
   end Is_Tag_Indeterminate;

   ------------------------------------
   -- Override_Dispatching_Operation --
   ------------------------------------

   procedure Override_Dispatching_Operation
     (Tagged_Type : Entity_Id;
      Prev_Op     : Entity_Id;
      New_Op      : Entity_Id)
   is
      Elmt : Elmt_Id;
      Prim : Node_Id;

   begin
      --  If there is no previous operation to override, the type declaration
      --  was malformed, and an error must have been emitted already.

      Elmt := First_Elmt (Primitive_Operations (Tagged_Type));
      while Present (Elmt) and then Node (Elmt) /= Prev_Op loop
         Next_Elmt (Elmt);
      end loop;

      if No (Elmt) then
         return;
      end if;

      --  The location of entities that come from source in the list of
      --  primitives of the tagged type must follow their order of occurrence
      --  in the sources to fulfill the C++ ABI. If the overridden entity is a
      --  primitive of an interface that is not implemented by the parents of
      --  this tagged type (that is, it is an alias of an interface primitive
      --  generated by Derive_Interface_Progenitors), then we must append the
      --  new entity at the end of the list of primitives.

      if Present (Alias (Prev_Op))
        and then Etype (Tagged_Type) /= Tagged_Type
        and then Is_Interface (Find_Dispatching_Type (Alias (Prev_Op)))
        and then not Is_Ancestor (Find_Dispatching_Type (Alias (Prev_Op)),
                                  Tagged_Type, Use_Full_View => True)
        and then not Implements_Interface
                       (Etype (Tagged_Type),
                        Find_Dispatching_Type (Alias (Prev_Op)))
      then
         Remove_Elmt (Primitive_Operations (Tagged_Type), Elmt);
         Add_Dispatching_Operation (Tagged_Type, New_Op);

      --  The new primitive replaces the overridden entity. Required to ensure
      --  that overriding primitive is assigned the same dispatch table slot.

      else
         Replace_Elmt (Elmt, New_Op);
      end if;

      if Ada_Version >= Ada_2005 and then Has_Interfaces (Tagged_Type) then

         --  Ada 2005 (AI-251): Update the attribute alias of all the aliased
         --  entities of the overridden primitive to reference New_Op, and
         --  also propagate the proper value of Is_Abstract_Subprogram. Verify
         --  that the new operation is subtype conformant with the interface
         --  operations that it implements (for operations inherited from the
         --  parent itself, this check is made when building the derived type).

         --  Note: This code is executed with internally generated wrappers of
         --  functions with controlling result and late overridings.

         Elmt := First_Elmt (Primitive_Operations (Tagged_Type));
         while Present (Elmt) loop
            Prim := Node (Elmt);

            if Prim = New_Op then
               null;

            --  Note: The check on Is_Subprogram protects the frontend against
            --  reading attributes in entities that are not yet fully decorated

            elsif Is_Subprogram (Prim)
              and then Present (Interface_Alias (Prim))
              and then Alias (Prim) = Prev_Op
            then
               Set_Alias (Prim, New_Op);

               --  No further decoration needed yet for internally generated
               --  wrappers of controlling functions since (at this stage)
               --  they are not yet decorated.

               if not Is_Wrapper (New_Op) then
                  Check_Subtype_Conformant (New_Op, Prim);

                  Set_Is_Abstract_Subprogram (Prim,
                    Is_Abstract_Subprogram (New_Op));

                  --  Ensure that this entity will be expanded to fill the
                  --  corresponding entry in its dispatch table.

                  if not Is_Abstract_Subprogram (Prim) then
                     Set_Has_Delayed_Freeze (Prim);
                  end if;
               end if;
            end if;

            Next_Elmt (Elmt);
         end loop;
      end if;

      if (not Is_Package_Or_Generic_Package (Current_Scope))
        or else not In_Private_Part (Current_Scope)
      then
         --  Not a private primitive

         null;

      else pragma Assert (Is_Inherited_Operation (Prev_Op));

         --  Make the overriding operation into an alias of the implicit one.
         --  In this fashion a call from outside ends up calling the new body
         --  even if non-dispatching, and a call from inside calls the over-
         --  riding operation because it hides the implicit one. To indicate
         --  that the body of Prev_Op is never called, set its dispatch table
         --  entity to Empty. If the overridden operation has a dispatching
         --  result, so does the overriding one.

         Set_Alias (Prev_Op, New_Op);
         Set_DTC_Entity (Prev_Op, Empty);
         Set_Has_Controlling_Result (New_Op, Has_Controlling_Result (Prev_Op));
         Set_Is_Ada_2022_Only (New_Op, Is_Ada_2022_Only (Prev_Op));
      end if;
   end Override_Dispatching_Operation;

   -------------------
   -- Propagate_Tag --
   -------------------

   procedure Propagate_Tag (Control : Node_Id; Actual : Node_Id) is
      Call_Node : Node_Id;
      Arg       : Node_Id;

   begin
      if Nkind (Actual) = N_Function_Call then
         Call_Node := Actual;

      elsif Nkind (Actual) = N_Identifier
        and then Nkind (Original_Node (Actual)) = N_Function_Call
      then
         --  Call rewritten as object declaration when stack-checking is
         --  enabled. Propagate tag to expression in declaration, which is
         --  original call.

         Call_Node := Expression (Parent (Entity (Actual)));

      --  Ada 2005: If this is a dereference of a call to a function with a
      --  dispatching access-result, the tag is propagated when the dereference
      --  itself is expanded (see exp_ch6.adb) and there is nothing else to do.

      elsif Nkind (Actual) = N_Explicit_Dereference
        and then Nkind (Original_Node (Prefix (Actual))) = N_Function_Call
      then
         return;

      --  When expansion is suppressed, an unexpanded call to 'Input can occur,
      --  and in that case we can simply return.

      elsif Nkind (Actual) = N_Attribute_Reference then
         pragma Assert (Attribute_Name (Actual) = Name_Input);

         return;

      --  Only other possibilities are parenthesized or qualified expression,
      --  or an expander-generated unchecked conversion of a function call to
      --  a stream Input attribute.

      else
         Call_Node := Expression (Actual);
      end if;

      --  No action needed if the call has been already expanded

      if Is_Expanded_Dispatching_Call (Call_Node) then
         return;
      end if;

      --  Do not set the Controlling_Argument if already set. This happens in
      --  the special case of _Input (see Exp_Attr, case Input).

      if No (Controlling_Argument (Call_Node)) then
         Set_Controlling_Argument (Call_Node, Control);
      end if;

      Arg := First_Actual (Call_Node);
      while Present (Arg) loop
         if Is_Tag_Indeterminate (Arg) then
            Propagate_Tag (Control,  Arg);
         end if;

         Next_Actual (Arg);
      end loop;

      --  Add class-wide precondition check if the target of this dispatching
      --  call has or inherits class-wide preconditions.

      Install_Class_Preconditions_Check (Call_Node);

      --  Expansion of dispatching calls is suppressed on VM targets, because
      --  the VM back-ends directly handle the generation of dispatching calls
      --  and would have to undo any expansion to an indirect call.

      if Tagged_Type_Expansion then
         declare
            Call_Typ : constant Entity_Id := Etype (Call_Node);

         begin
            Expand_Dispatching_Call (Call_Node);

            --  If the controlling argument is an interface type and the type
            --  of Call_Node differs then we must add an implicit conversion to
            --  force displacement of the pointer to the object to reference
            --  the secondary dispatch table of the interface.

            if Is_Interface (Etype (Control))
              and then Etype (Control) /= Call_Typ
            then
               --  Cannot use Convert_To because the previous call to
               --  Expand_Dispatching_Call leaves decorated the Call_Node
               --  with the type of Control.

               Rewrite (Call_Node,
                 Make_Type_Conversion (Sloc (Call_Node),
                   Subtype_Mark =>
                     New_Occurrence_Of (Etype (Control), Sloc (Call_Node)),
                   Expression => Relocate_Node (Call_Node)));
               Set_Etype (Call_Node, Etype (Control));
               Set_Analyzed (Call_Node);

               Expand_Interface_Conversion (Call_Node);
            end if;
         end;

      --  Expansion of a dispatching call results in an indirect call, which in
      --  turn causes current values to be killed (see Resolve_Call), so on VM
      --  targets we do the call here to ensure consistent warnings between VM
      --  and non-VM targets.

      else
         Kill_Current_Values;
      end if;
   end Propagate_Tag;

end Sem_Disp;
