OSDN Git Service

libitm: Remove unused code.
[pf3gnuchains/gcc-fork.git] / gcc / ada / exp_ch9.adb
index ca4d70b..8305278 100644 (file)
@@ -6,7 +6,7 @@
 --                                                                          --
 --                                 B o d y                                  --
 --                                                                          --
---          Copyright (C) 1992-2008, Free Software Foundation, Inc.         --
+--          Copyright (C) 1992-2011, 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- --
@@ -29,9 +29,10 @@ with Einfo;    use Einfo;
 with Elists;   use Elists;
 with Errout;   use Errout;
 with Exp_Ch3;  use Exp_Ch3;
-with Exp_Ch11; use Exp_Ch11;
 with Exp_Ch6;  use Exp_Ch6;
+with Exp_Ch11; use Exp_Ch11;
 with Exp_Dbug; use Exp_Dbug;
+with Exp_Disp; use Exp_Disp;
 with Exp_Sel;  use Exp_Sel;
 with Exp_Smem; use Exp_Smem;
 with Exp_Tss;  use Exp_Tss;
@@ -47,15 +48,18 @@ with Restrict; use Restrict;
 with Rident;   use Rident;
 with Rtsfind;  use Rtsfind;
 with Sem;      use Sem;
+with Sem_Aux;  use Sem_Aux;
 with Sem_Ch6;  use Sem_Ch6;
 with Sem_Ch8;  use Sem_Ch8;
 with Sem_Ch11; use Sem_Ch11;
 with Sem_Elab; use Sem_Elab;
+with Sem_Eval; use Sem_Eval;
 with Sem_Res;  use Sem_Res;
 with Sem_Util; use Sem_Util;
 with Sinfo;    use Sinfo;
 with Snames;   use Snames;
 with Stand;    use Stand;
+with Stringt;  use Stringt;
 with Targparm; use Targparm;
 with Tbuild;   use Tbuild;
 with Uintp;    use Uintp;
@@ -67,8 +71,7 @@ package body Exp_Ch9 is
    --  types with defaulted discriminant of an integer type, when the bound
    --  of some entry family depends on a discriminant. The limitation to
    --  entry families of 128K should be reasonable in all cases, and is a
-   --  documented implementation restriction. It will be lifted when protected
-   --  entry families are re-implemented as a single ordered queue.
+   --  documented implementation restriction.
 
    Entry_Family_Bound : constant Int := 2**16;
 
@@ -124,6 +127,14 @@ package body Exp_Ch9 is
    --  Build a specification for a function implementing the protected entry
    --  barrier of the specified entry body.
 
+   function Build_Corresponding_Record
+     (N    : Node_Id;
+      Ctyp : Node_Id;
+      Loc  : Source_Ptr) return Node_Id;
+   --  Common to tasks and protected types. Copy discriminant specifications,
+   --  build record declaration. N is the type declaration, Ctyp is the
+   --  concurrent entity (task type or protected type).
+
    function Build_Entry_Count_Expression
      (Concurrent_Type : Node_Id;
       Component_List  : List_Id;
@@ -150,29 +161,46 @@ package body Exp_Ch9 is
    --       <formalN> : AnnN;
    --    end record;
 
-   function Build_Wrapper_Body
-     (Loc      : Source_Ptr;
-      Proc_Nam : Entity_Id;
-      Obj_Typ  : Entity_Id;
-      Formals  : List_Id) return Node_Id;
-   --  Ada 2005 (AI-345): Build the body that wraps a primitive operation
-   --  associated with a protected or task type. This is required to implement
-   --  dispatching calls through interfaces. Proc_Nam is the entry name to be
-   --  wrapped, Obj_Typ is the type of the newly added formal parameter to
-   --  handle object notation, Formals are the original entry formals that will
-   --  be explicitly replicated.
-
-   function Build_Wrapper_Spec
-     (Loc      : Source_Ptr;
-      Proc_Nam : Entity_Id;
-      Obj_Typ  : Entity_Id;
-      Formals  : List_Id) return Node_Id;
-   --  Ada 2005 (AI-345): Build the specification of a primitive operation
-   --  associated with a protected or task type. This is required implement
-   --  dispatching calls through interfaces. Proc_Nam is the entry name to be
-   --  wrapped, Obj_Typ is the type of the newly added formal parameter to
-   --  handle object notation, Formals are the original entry formals that will
-   --  be explicitly replicated.
+   procedure Build_PPC_Wrapper (E : Entity_Id; Decl : Node_Id);
+   --  Build body of wrapper procedure for an entry or entry family that has
+   --  pre/postconditions. The body gathers the PPC's and expands them in the
+   --  usual way, and performs the entry call itself. This way preconditions
+   --  are evaluated before the call is queued. E is the entry in question,
+   --  and Decl is the enclosing synchronized type declaration at whose
+   --  freeze point the generated body is analyzed.
+
+   function Build_Renamed_Formal_Declaration
+     (New_F          : Entity_Id;
+      Formal         : Entity_Id;
+      Comp           : Entity_Id;
+      Renamed_Formal : Node_Id) return Node_Id;
+   --  Create a renaming declaration for a formal, within a protected entry
+   --  body or an accept body. The renamed object is a component of the
+   --  parameter block that is a parameter in the entry call.
+
+   --  In Ada 2012, if the formal is an incomplete tagged type, the renaming
+   --  does not dereference the corresponding component to prevent an illegal
+   --  use of the incomplete type (AI05-0151).
+
+   procedure Build_Wrapper_Bodies
+     (Loc : Source_Ptr;
+      Typ : Entity_Id;
+      N   : Node_Id);
+   --  Ada 2005 (AI-345): Typ is either a concurrent type or the corresponding
+   --  record of a concurrent type. N is the insertion node where all bodies
+   --  will be placed. This routine builds the bodies of the subprograms which
+   --  serve as an indirection mechanism to overriding primitives of concurrent
+   --  types, entries and protected procedures. Any new body is analyzed.
+
+   procedure Build_Wrapper_Specs
+     (Loc : Source_Ptr;
+      Typ : Entity_Id;
+      N   : in out Node_Id);
+   --  Ada 2005 (AI-345): Typ is either a concurrent type or the corresponding
+   --  record of a concurrent type. N is the insertion node where all specs
+   --  will be placed. This routine builds the specs of the subprograms which
+   --  serve as an indirection mechanism to overriding primitives of concurrent
+   --  types, entries and protected procedures. Any new spec is analyzed.
 
    function Build_Find_Body_Index (Typ : Entity_Id) return Node_Id;
    --  Build the function that translates the entry index in the call
@@ -300,7 +328,7 @@ package body Exp_Ch9 is
       Lo   : Node_Id;
       Ttyp : Entity_Id;
       Cap  : Boolean) return Node_Id;
-   --  Compute (Hi - Lo) for two entry family indices. Hi is the index in
+   --  Compute (Hi - Lo) for two entry family indexes. Hi is the index in
    --  an accept statement, or the upper bound in the discrete subtype of
    --  an entry declaration. Lo is the corresponding lower bound. Ttyp is
    --  the concurrent type of the entry. If Cap is true, the result is
@@ -318,6 +346,18 @@ package body Exp_Ch9 is
    --  to handle properly the case of bounds that depend on discriminants.
    --  If Cap is true, the result is capped according to Entry_Family_Bound.
 
+   procedure Find_Enclosing_Context
+     (N             : Node_Id;
+      Context       : out Node_Id;
+      Context_Id    : out Entity_Id;
+      Context_Decls : out List_Id);
+   --  Subsidiary routine to procedures Build_Activation_Chain_Entity and
+   --  Build_Master_Entity. Given an arbitrary node in the tree, find the
+   --  nearest enclosing body, block, package or return statement and return
+   --  its constituents. Context is the enclosing construct, Context_Id is
+   --  the scope of Context_Id and Context_Decls is the declarative list of
+   --  Context.
+
    procedure Extract_Dispatching_Call
      (N        : Node_Id;
       Call_Ent : out Entity_Id;
@@ -325,8 +365,10 @@ package body Exp_Ch9 is
       Actuals  : out List_Id;
       Formals  : out List_Id);
    --  Given a dispatching call, extract the entity of the name of the call,
-   --  its object parameter, its actual parameters and the formal parameters
-   --  of the overridden interface-level version.
+   --  its actual dispatching object, its actual parameters and the formal
+   --  parameters of the overridden interface-level version. If the type of
+   --  the dispatching object is an access type then an explicit dereference
+   --  is returned in Object.
 
    procedure Extract_Entry
      (N       : Node_Id;
@@ -357,6 +399,10 @@ package body Exp_Ch9 is
       Lo         : Node_Id;
       Hi         : Node_Id) return Boolean;
 
+   function Is_Private_Primitive_Subprogram (Id : Entity_Id) return Boolean;
+   --  Determine whether Id is a function or a procedure and is marked as a
+   --  private primitive.
+
    function Null_Statements (Stats : List_Id) return Boolean;
    --  Used to check DO-END sequence. Checks for equivalent of DO NULL; END.
    --  Allows labels, and pragma Warnings/Unreferenced in the sequence as
@@ -615,10 +661,11 @@ package body Exp_Ch9 is
       --  The name of the formal that holds the address of the parameter block
       --  for the call.
 
-      Comp   : Entity_Id;
-      Decl   : Node_Id;
-      Formal : Entity_Id;
-      New_F  : Entity_Id;
+      Comp            : Entity_Id;
+      Decl            : Node_Id;
+      Formal          : Entity_Id;
+      New_F           : Entity_Id;
+      Renamed_Formal  : Node_Id;
 
    begin
       Formal := First_Formal (Ent);
@@ -645,19 +692,16 @@ package body Exp_Ch9 is
 
          Set_Actual_Subtype (New_F, Actual_Subtype (Formal));
 
+         Renamed_Formal :=
+           Make_Selected_Component (Loc,
+             Prefix        =>
+               Unchecked_Convert_To (Entry_Parameters_Type (Ent),
+                 Make_Identifier (Loc, Chars (Ptr))),
+             Selector_Name => New_Reference_To (Comp, Loc));
+
          Decl :=
-           Make_Object_Renaming_Declaration (Loc,
-           Defining_Identifier => New_F,
-           Subtype_Mark =>
-             New_Reference_To (Etype (Formal), Loc),
-           Name =>
-             Make_Explicit_Dereference (Loc,
-               Make_Selected_Component (Loc,
-                 Prefix =>
-                   Unchecked_Convert_To (Entry_Parameters_Type (Ent),
-                     Make_Identifier (Loc, Chars (Ptr))),
-                 Selector_Name =>
-                   New_Reference_To (Comp, Loc))));
+           Build_Renamed_Formal_Declaration
+             (New_F, Formal, Comp, Renamed_Formal);
 
          Append (Decl, Decls);
          Set_Renamed_Object (Formal, New_F);
@@ -699,8 +743,7 @@ package body Exp_Ch9 is
           Object_Definition =>
             New_Reference_To (Obj_Ptr, Loc),
           Expression =>
-            Unchecked_Convert_To (Obj_Ptr,
-              Make_Identifier (Loc, Name_uO)));
+            Unchecked_Convert_To (Obj_Ptr, Make_Identifier (Loc, Name_uO)));
       Set_Debug_Info_Needed (Defining_Identifier (Decl));
       Prepend_To (Decls, Decl);
 
@@ -713,8 +756,8 @@ package body Exp_Ch9 is
             Obj_Ptr,
           Type_Definition =>
             Make_Access_To_Object_Definition (Loc,
-          Subtype_Indication =>
-            New_Reference_To (Rec_Typ, Loc)));
+              Subtype_Indication =>
+                New_Reference_To (Rec_Typ, Loc)));
       Set_Debug_Info_Needed (Defining_Identifier (Decl));
       Prepend_To (Decls, Decl);
    end Add_Object_Pointer;
@@ -735,20 +778,25 @@ package body Exp_Ch9 is
       --  At the end of the statement sequence, Complete_Rendezvous is called.
       --  A label skipping the Complete_Rendezvous, and all other accept
       --  processing, has already been added for the expansion of requeue
-      --  statements.
+      --  statements. The Sloc is copied from the last statement since it
+      --  is really part of this last statement.
 
-      Call := Build_Runtime_Call (Loc, RE_Complete_Rendezvous);
+      Call :=
+        Build_Runtime_Call
+          (Sloc (Last (Statements (Stats))), RE_Complete_Rendezvous);
       Insert_Before (Last (Statements (Stats)), Call);
       Analyze (Call);
 
       --  If exception handlers are present, then append Complete_Rendezvous
-      --  calls to the handlers, and construct the required outer block.
+      --  calls to the handlers, and construct the required outer block. As
+      --  above, the Sloc is copied from the last statement in the sequence.
 
       if Present (Exception_Handlers (Stats)) then
          Hand := First (Exception_Handlers (Stats));
-
          while Present (Hand) loop
-            Call := Build_Runtime_Call (Loc, RE_Complete_Rendezvous);
+            Call :=
+              Build_Runtime_Call
+                (Sloc (Last (Statements (Hand))), RE_Complete_Rendezvous);
             Append (Call, Statements (Hand));
             Analyze (Call);
             Next (Hand);
@@ -783,13 +831,13 @@ package body Exp_Ch9 is
             Exception_Choices => New_List (Ohandle),
 
             Statements =>  New_List (
-              Make_Procedure_Call_Statement (Loc,
+              Make_Procedure_Call_Statement (Sloc (Stats),
                 Name => New_Reference_To (
-                  RTE (RE_Exceptional_Complete_Rendezvous), Loc),
+                  RTE (RE_Exceptional_Complete_Rendezvous), Sloc (Stats)),
                 Parameter_Associations => New_List (
-                  Make_Function_Call (Loc,
+                  Make_Function_Call (Sloc (Stats),
                     Name => New_Reference_To (
-                      RTE (RE_Get_GNAT_Exception), Loc))))))));
+                      RTE (RE_Get_GNAT_Exception), Sloc (Stats)))))))));
 
       Set_Parent (New_S, Astat); -- temp parent for Analyze call
       Analyze_Exception_Handlers (Exception_Handlers (New_S));
@@ -806,70 +854,100 @@ package body Exp_Ch9 is
    -----------------------------------
 
    procedure Build_Activation_Chain_Entity (N : Node_Id) is
-      P     : Node_Id;
-      Decls : List_Id;
-      Chain : Entity_Id;
+      function Has_Activation_Chain (Stmt : Node_Id) return Boolean;
+      --  Determine whether an extended return statement has an activation
+      --  chain.
 
-   begin
-      --  Loop to find enclosing construct containing activation chain variable
+      --------------------------
+      -- Has_Activation_Chain --
+      --------------------------
 
-      P := Parent (N);
+      function Has_Activation_Chain (Stmt : Node_Id) return Boolean is
+         Decl : Node_Id;
 
-      while not Nkind_In (P, N_Subprogram_Body,
-                             N_Package_Declaration,
-                             N_Package_Body,
-                             N_Block_Statement,
-                             N_Task_Body,
-                             N_Extended_Return_Statement)
-      loop
-         P := Parent (P);
-      end loop;
+      begin
+         Decl := First (Return_Object_Declarations (Stmt));
+         while Present (Decl) loop
+            if Nkind (Decl) = N_Object_Declaration
+              and then Chars (Defining_Identifier (Decl)) = Name_uChain
+            then
+               return True;
+            end if;
+
+            Next (Decl);
+         end loop;
 
-      --  If we are in a package body, the activation chain variable is
-      --  declared in the body, but the Activation_Chain_Entity is attached to
-      --  the spec.
+         return False;
+      end Has_Activation_Chain;
 
-      if Nkind (P) = N_Package_Body then
-         Decls := Declarations (P);
-         P := Unit_Declaration_Node (Corresponding_Spec (P));
+      --  Local variables
 
-      elsif Nkind (P) = N_Package_Declaration then
-         Decls := Visible_Declarations (Specification (P));
+      Context    : Node_Id;
+      Context_Id : Entity_Id;
+      Decls      : List_Id;
 
-      elsif Nkind (P) = N_Extended_Return_Statement then
-         Decls := Return_Object_Declarations (P);
+   --  Start of processing for Build_Activation_Chain_Entity
 
-      else
-         Decls := Declarations (P);
-      end if;
+   begin
+      Find_Enclosing_Context (N, Context, Context_Id, Decls);
 
-      --  If activation chain entity not already declared, declare it
+      --  If an activation chain entity has not been declared already, create
+      --  one.
 
-      if Nkind (P) = N_Extended_Return_Statement
-        or else No (Activation_Chain_Entity (P))
+      if Nkind (Context) = N_Extended_Return_Statement
+        or else No (Activation_Chain_Entity (Context))
       then
-         Chain := Make_Defining_Identifier (Sloc (N), Name_uChain);
-
-         --  Note: An extended return statement is not really a task activator,
-         --  but it does have an activation chain on which to store the tasks
-         --  temporarily. On successful return, the tasks on this chain are
-         --  moved to the chain passed in by the caller. We do not build an
-         --  Activation_Chain_Entity for an N_Extended_Return_Statement,
-         --  because we do not want to build a call to Activate_Tasks. Task
-         --  activation is the responsibility of the caller.
-
-         if Nkind (P) /= N_Extended_Return_Statement then
-            Set_Activation_Chain_Entity (P, Chain);
+         --  Since extended return statements do not store the entity of the
+         --  chain, examine the return object declarations to avoid creating
+         --  a duplicate.
+
+         if Nkind (Context) = N_Extended_Return_Statement
+           and then Has_Activation_Chain (Context)
+         then
+            return;
          end if;
 
-         Prepend_To (Decls,
-           Make_Object_Declaration (Sloc (P),
-             Defining_Identifier => Chain,
-             Aliased_Present => True,
-             Object_Definition =>
-               New_Reference_To (RTE (RE_Activation_Chain), Sloc (P))));
+         declare
+            Loc   : constant Source_Ptr := Sloc (Context);
+            Chain : Entity_Id;
+            Decl  : Node_Id;
+
+         begin
+            Chain := Make_Defining_Identifier (Sloc (N), Name_uChain);
+
+            --  Note: An extended return statement is not really a task
+            --  activator, but it does have an activation chain on which to
+            --  store the tasks temporarily. On successful return, the tasks
+            --  on this chain are moved to the chain passed in by the caller.
+            --  We do not build an Activation_Chain_Entity for an extended
+            --  return statement, because we do not want to build a call to
+            --  Activate_Tasks. Task activation is the responsibility of the
+            --  caller.
+
+            if Nkind (Context) /= N_Extended_Return_Statement then
+               Set_Activation_Chain_Entity (Context, Chain);
+            end if;
 
-         Analyze (First (Decls));
+            Decl :=
+              Make_Object_Declaration (Loc,
+                Defining_Identifier => Chain,
+                Aliased_Present     => True,
+                Object_Definition   =>
+                  New_Reference_To (RTE (RE_Activation_Chain), Loc));
+
+            Prepend_To (Decls, Decl);
+
+            --  Ensure that the _chain appears in the proper scope of the
+            --  context.
+
+            if Context_Id /= Current_Scope then
+               Push_Scope (Context_Id);
+               Analyze (Decl);
+               Pop_Scope;
+            else
+               Analyze (Decl);
+            end if;
+         end;
       end if;
    end Build_Activation_Chain_Entity;
 
@@ -882,10 +960,12 @@ package body Exp_Ch9 is
       Ent : Entity_Id;
       Pid : Node_Id) return Node_Id
    is
-      Loc         : constant Source_Ptr := Sloc (N);
-      Func_Id     : constant Entity_Id  := Barrier_Function (Ent);
       Ent_Formals : constant Node_Id    := Entry_Body_Formal_Part (N);
+      Cond        : constant Node_Id    := Condition (Ent_Formals);
+      Loc         : constant Source_Ptr := Sloc (Cond);
+      Func_Id     : constant Entity_Id  := Barrier_Function (Ent);
       Op_Decls    : constant List_Id    := New_List;
+      Stmt        : Node_Id;
       Func_Body   : Node_Id;
 
    begin
@@ -893,8 +973,32 @@ package body Exp_Ch9 is
       --  for the discriminals and privals and finally a declaration for the
       --  entry family index (if applicable).
 
-      Install_Private_Data_Declarations
-        (Loc, Func_Id, Pid, N, Op_Decls, True, Ekind (Ent) = E_Entry_Family);
+      Install_Private_Data_Declarations (Sloc (N),
+         Spec_Id  => Func_Id,
+         Conc_Typ => Pid,
+         Body_Nod => N,
+         Decls    => Op_Decls,
+         Barrier  => True,
+         Family   => Ekind (Ent) = E_Entry_Family);
+
+      --  If compiling with -fpreserve-control-flow, make sure we insert an
+      --  IF statement so that the back-end knows to generate a conditional
+      --  branch instruction, even if the condition is just the name of a
+      --  boolean object.
+
+      if Opt.Suppress_Control_Flow_Optimizations then
+         Stmt := Make_Implicit_If_Statement (Cond,
+                   Condition       => Cond,
+                   Then_Statements => New_List (
+                     Make_Simple_Return_Statement (Loc,
+                       New_Occurrence_Of (Standard_True, Loc))),
+                   Else_Statements => New_List (
+                     Make_Simple_Return_Statement (Loc,
+                       New_Occurrence_Of (Standard_False, Loc))));
+
+      else
+         Stmt := Make_Simple_Return_Statement (Loc, Cond);
+      end if;
 
       --  Note: the condition in the barrier function needs to be properly
       --  processed for the C/Fortran boolean possibility, but this happens
@@ -908,9 +1012,7 @@ package body Exp_Ch9 is
           Declarations => Op_Decls,
           Handled_Statement_Sequence =>
             Make_Handled_Sequence_Of_Statements (Loc,
-              Statements => New_List (
-                Make_Simple_Return_Statement (Loc,
-                  Expression => Condition (Ent_Formals)))));
+              Statements => New_List (Stmt)));
       Set_Is_Entry_Barrier_Function (Func_Body);
 
       return Func_Body;
@@ -962,6 +1064,127 @@ package body Exp_Ch9 is
           Parameter_Associations => New_List (Concurrent_Ref (N)));
    end Build_Call_With_Task;
 
+   -----------------------------
+   -- Build_Class_Wide_Master --
+   -----------------------------
+
+   procedure Build_Class_Wide_Master (Typ : Entity_Id) is
+      Loc          : constant Source_Ptr := Sloc (Typ);
+      Master_Id    : Entity_Id;
+      Master_Scope : Entity_Id;
+      Name_Id      : Node_Id;
+      Related_Node : Node_Id;
+      Ren_Decl     : Node_Id;
+
+   begin
+      --  Nothing to do if there is no task hierarchy
+
+      if Restriction_Active (No_Task_Hierarchy) then
+         return;
+      end if;
+
+      --  Find the declaration that created the access type. It is either a
+      --  type declaration, or an object declaration with an access definition,
+      --  in which case the type is anonymous.
+
+      if Is_Itype (Typ) then
+         Related_Node := Associated_Node_For_Itype (Typ);
+      else
+         Related_Node := Parent (Typ);
+      end if;
+
+      Master_Scope := Find_Master_Scope (Typ);
+
+      --  Nothing to do if the master scope already contains a _master entity.
+      --  The only exception to this is the following scenario:
+
+      --    Source_Scope
+      --       Transient_Scope_1
+      --          _master
+
+      --       Transient_Scope_2
+      --          use of master
+
+      --  In this case the source scope is marked as having the master entity
+      --  even though the actual declaration appears inside an inner scope. If
+      --  the second transient scope requires a _master, it cannot use the one
+      --  already declared because the entity is not visible.
+
+      Name_Id := Make_Identifier (Loc, Name_uMaster);
+
+      if not Has_Master_Entity (Master_Scope)
+        or else No (Current_Entity_In_Scope (Name_Id))
+      then
+         declare
+            Master_Decl : Node_Id;
+
+         begin
+            Set_Has_Master_Entity (Master_Scope);
+
+            --  Generate:
+            --    _master : constant Integer := Current_Master.all;
+
+            Master_Decl :=
+              Make_Object_Declaration (Loc,
+                Defining_Identifier =>
+                  Make_Defining_Identifier (Loc, Name_uMaster),
+                Constant_Present    => True,
+                Object_Definition   =>
+                  New_Reference_To (Standard_Integer, Loc),
+                Expression          =>
+                  Make_Explicit_Dereference (Loc,
+                    New_Reference_To (RTE (RE_Current_Master), Loc)));
+
+            Insert_Action (Related_Node, Master_Decl);
+            Analyze (Master_Decl);
+
+            --  Mark the containing scope as a task master. Masters associated
+            --  with return statements are already marked at this stage (see
+            --  Analyze_Subprogram_Body).
+
+            if Ekind (Current_Scope) /= E_Return_Statement then
+               declare
+                  Par : Node_Id := Related_Node;
+
+               begin
+                  while Nkind (Par) /= N_Compilation_Unit loop
+                     Par := Parent (Par);
+
+                     --  If we fall off the top, we are at the outer level, and
+                     --  the environment task is our effective master, so
+                     --  nothing to mark.
+
+                     if Nkind_In (Par, N_Block_Statement,
+                                       N_Subprogram_Body,
+                                       N_Task_Body)
+                     then
+                        Set_Is_Task_Master (Par);
+                        exit;
+                     end if;
+                  end loop;
+               end;
+            end if;
+         end;
+      end if;
+
+      Master_Id :=
+        Make_Defining_Identifier (Loc,
+          New_External_Name (Chars (Typ), 'M'));
+
+      --  Generate:
+      --    Mnn renames _master;
+
+      Ren_Decl :=
+        Make_Object_Renaming_Declaration (Loc,
+          Defining_Identifier => Master_Id,
+          Subtype_Mark        => New_Reference_To (Standard_Integer, Loc),
+          Name                => Name_Id);
+
+      Insert_Action (Related_Node, Ren_Decl);
+
+      Set_Master_Id (Typ, Master_Id);
+   end Build_Class_Wide_Master;
+
    --------------------------------
    -- Build_Corresponding_Record --
    --------------------------------
@@ -1000,7 +1223,7 @@ package body Exp_Ch9 is
       --     for the task body.
 
       --  In fact the discriminals b) are used in the renaming declarations
-      --  for e). See details in  einfo (Handling of Discriminants).
+      --  for e). See details in einfo (Handling of Discriminants).
 
       if Present (Discriminant_Specifications (N)) then
          Dlist := New_List;
@@ -1028,8 +1251,9 @@ package body Exp_Ch9 is
       --  record is "limited tagged". It is "limited" to reflect the underlying
       --  limitedness of the task or protected object that it represents, and
       --  ensuring for example that it is properly passed by reference. It is
-      --  "tagged" to give support to dispatching calls through interfaces (Ada
-      --  2005: AI-345)
+      --  "tagged" to give support to dispatching calls through interfaces. We
+      --  propagate here the list of interfaces covered by the concurrent type
+      --  (Ada 2005: AI-345).
 
       return
         Make_Full_Type_Declaration (Loc,
@@ -1041,7 +1265,8 @@ package body Exp_Ch9 is
                 Make_Component_List (Loc,
                   Component_Items => Cdecls),
               Tagged_Present  =>
-                 Ada_Version >= Ada_05 and then Is_Tagged_Type (Ctyp),
+                 Ada_Version >= Ada_2005 and then Is_Tagged_Type (Ctyp),
+              Interface_List  => Interface_List (N),
               Limited_Present => True));
    end Build_Corresponding_Record;
 
@@ -1106,6 +1331,315 @@ package body Exp_Ch9 is
       return Ecount;
    end Build_Entry_Count_Expression;
 
+   -----------------------
+   -- Build_Entry_Names --
+   -----------------------
+
+   function Build_Entry_Names (Conc_Typ : Entity_Id) return Node_Id is
+      Loc       : constant Source_Ptr := Sloc (Conc_Typ);
+      B_Decls   : List_Id;
+      B_Stmts   : List_Id;
+      Comp      : Node_Id;
+      Index     : Entity_Id;
+      Index_Typ : RE_Id;
+      Typ       : Entity_Id := Conc_Typ;
+
+      procedure Build_Entry_Family_Name (Id : Entity_Id);
+      --  Generate:
+      --    for Lnn in Family_Low .. Family_High loop
+      --       Inn := Inn + 1;
+      --       Set_Entry_Name
+      --         (_init._object <or> _init._task_id,
+      --          Inn,
+      --          new String ("<Entry name>(" & Lnn'Img & ")"));
+      --    end loop;
+      --  Note that the bounds of the range may reference discriminants. The
+      --  above construct is added directly to the statements of the block.
+
+      procedure Build_Entry_Name (Id : Entity_Id);
+      --  Generate:
+      --    Inn := Inn + 1;
+      --    Set_Entry_Name
+      --      (_init._object <or>_init._task_id,
+      --       Inn,
+      --       new String ("<Entry name>");
+      --  The above construct is added directly to the statements of the block.
+
+      function Build_Set_Entry_Name_Call (Arg3 : Node_Id) return Node_Id;
+      --  Generate the call to the runtime routine Set_Entry_Name with actuals
+      --  _init._task_id or _init._object, Inn and Arg3.
+
+      procedure Increment_Index (Stmts : List_Id);
+      --  Generate the following and add it to Stmts
+      --    Inn := Inn + 1;
+
+      -----------------------------
+      -- Build_Entry_Family_Name --
+      -----------------------------
+
+      procedure Build_Entry_Family_Name (Id : Entity_Id) is
+         Def     : constant Node_Id :=
+                     Discrete_Subtype_Definition (Parent (Id));
+         L_Id    : constant Entity_Id := Make_Temporary (Loc, 'L');
+         L_Stmts : constant List_Id := New_List;
+         Val     : Node_Id;
+
+         function Build_Range (Def : Node_Id) return Node_Id;
+         --  Given a discrete subtype definition of an entry family, generate a
+         --  range node which covers the range of Def's type.
+
+         -----------------
+         -- Build_Range --
+         -----------------
+
+         function Build_Range (Def : Node_Id) return Node_Id is
+            High : Node_Id := Type_High_Bound (Etype (Def));
+            Low  : Node_Id := Type_Low_Bound  (Etype (Def));
+
+         begin
+            --  If a bound references a discriminant, generate an identifier
+            --  with the same name. Resolution will map it to the formals of
+            --  the init proc.
+
+            if Is_Entity_Name (Low)
+              and then Ekind (Entity (Low)) = E_Discriminant
+            then
+               Low := Make_Identifier (Loc, Chars (Low));
+            else
+               Low := New_Copy_Tree (Low);
+            end if;
+
+            if Is_Entity_Name (High)
+              and then Ekind (Entity (High)) = E_Discriminant
+            then
+               High := Make_Identifier (Loc, Chars (High));
+            else
+               High := New_Copy_Tree (High);
+            end if;
+
+            return
+              Make_Range (Loc,
+                Low_Bound  => Low,
+                High_Bound => High);
+         end Build_Range;
+
+      --  Start of processing for Build_Entry_Family_Name
+
+      begin
+         Get_Name_String (Chars (Id));
+
+         --  Add a leading '('
+
+         Add_Char_To_Name_Buffer ('(');
+
+         --  Generate:
+         --    new String'("<Entry name>(" & Lnn'Img & ")");
+
+         --  This is an implicit heap allocation, and Comes_From_Source is
+         --  False, which ensures that it will get flagged as a violation of
+         --  No_Implicit_Heap_Allocations when that restriction applies.
+
+         Val :=
+           Make_Allocator (Loc,
+             Make_Qualified_Expression (Loc,
+               Subtype_Mark =>
+                 New_Reference_To (Standard_String, Loc),
+               Expression =>
+                 Make_Op_Concat (Loc,
+                   Left_Opnd =>
+                     Make_Op_Concat (Loc,
+                       Left_Opnd =>
+                         Make_String_Literal (Loc,
+                           Strval => String_From_Name_Buffer),
+                       Right_Opnd =>
+                         Make_Attribute_Reference (Loc,
+                           Prefix =>
+                             New_Reference_To (L_Id, Loc),
+                               Attribute_Name => Name_Img)),
+                   Right_Opnd =>
+                     Make_String_Literal (Loc,
+                       Strval => ")"))));
+
+         Increment_Index (L_Stmts);
+         Append_To (L_Stmts, Build_Set_Entry_Name_Call (Val));
+
+         --  Generate:
+         --    for Lnn in Family_Low .. Family_High loop
+         --       Inn := Inn + 1;
+         --       Set_Entry_Name
+         --         (_init._object <or> _init._task_id, Inn, <Val>);
+         --    end loop;
+
+         Append_To (B_Stmts,
+           Make_Loop_Statement (Loc,
+             Iteration_Scheme =>
+               Make_Iteration_Scheme (Loc,
+                 Loop_Parameter_Specification =>
+                   Make_Loop_Parameter_Specification (Loc,
+                    Defining_Identifier         => L_Id,
+                    Discrete_Subtype_Definition => Build_Range (Def))),
+             Statements => L_Stmts,
+             End_Label => Empty));
+      end Build_Entry_Family_Name;
+
+      ----------------------
+      -- Build_Entry_Name --
+      ----------------------
+
+      procedure Build_Entry_Name (Id : Entity_Id) is
+         Val : Node_Id;
+
+      begin
+         Get_Name_String (Chars (Id));
+
+         --  This is an implicit heap allocation, and Comes_From_Source is
+         --  False, which ensures that it will get flagged as a violation of
+         --  No_Implicit_Heap_Allocations when that restriction applies.
+
+         Val :=
+           Make_Allocator (Loc,
+             Make_Qualified_Expression (Loc,
+               Subtype_Mark =>
+                 New_Reference_To (Standard_String, Loc),
+               Expression =>
+                 Make_String_Literal (Loc,
+                   String_From_Name_Buffer)));
+
+         Increment_Index (B_Stmts);
+         Append_To (B_Stmts, Build_Set_Entry_Name_Call (Val));
+      end Build_Entry_Name;
+
+      -------------------------------
+      -- Build_Set_Entry_Name_Call --
+      -------------------------------
+
+      function Build_Set_Entry_Name_Call (Arg3 : Node_Id) return Node_Id is
+         Arg1 : Name_Id;
+         Proc : RE_Id;
+
+      begin
+         --  Determine the proper name for the first argument and the RTS
+         --  routine to call.
+
+         if Is_Protected_Type (Typ) then
+            Arg1 := Name_uObject;
+            Proc := RO_PE_Set_Entry_Name;
+
+         else pragma Assert (Is_Task_Type (Typ));
+            Arg1 := Name_uTask_Id;
+            Proc := RO_TS_Set_Entry_Name;
+         end if;
+
+         --  Generate:
+         --    Set_Entry_Name (_init.Arg1, Inn, Arg3);
+
+         return
+           Make_Procedure_Call_Statement (Loc,
+             Name =>
+               New_Reference_To (RTE (Proc), Loc),
+             Parameter_Associations => New_List (
+               Make_Selected_Component (Loc,              --  _init._object
+                 Prefix =>                                --  _init._task_id
+                   Make_Identifier (Loc, Name_uInit),
+                 Selector_Name =>
+                   Make_Identifier (Loc, Arg1)),
+               New_Reference_To (Index, Loc),             --  Inn
+               Arg3));                                    --  Val
+      end Build_Set_Entry_Name_Call;
+
+      ---------------------
+      -- Increment_Index --
+      ---------------------
+
+      procedure Increment_Index (Stmts : List_Id) is
+      begin
+         --  Generate:
+         --    Inn := Inn + 1;
+
+         Append_To (Stmts,
+           Make_Assignment_Statement (Loc,
+             Name =>
+               New_Reference_To (Index, Loc),
+             Expression =>
+               Make_Op_Add (Loc,
+                 Left_Opnd =>
+                   New_Reference_To (Index, Loc),
+                 Right_Opnd =>
+                   Make_Integer_Literal (Loc, 1))));
+      end Increment_Index;
+
+   --  Start of processing for Build_Entry_Names
+
+   begin
+      --  Retrieve the original concurrent type
+
+      if Is_Concurrent_Record_Type (Typ) then
+         Typ := Corresponding_Concurrent_Type (Typ);
+      end if;
+
+      pragma Assert (Is_Protected_Type (Typ) or else Is_Task_Type (Typ));
+
+      --  Nothing to do if the type has no entries
+
+      if not Has_Entries (Typ) then
+         return Empty;
+      end if;
+
+      --  Avoid generating entry names for a protected type with only one entry
+
+      if Is_Protected_Type (Typ)
+        and then Find_Protection_Type (Typ) /= RTE (RE_Protection_Entries)
+      then
+         return Empty;
+      end if;
+
+      Index := Make_Temporary (Loc, 'I');
+
+      --  Step 1: Generate the declaration of the index variable:
+      --    Inn : Protected_Entry_Index := 0;
+      --      or
+      --    Inn : Task_Entry_Index := 0;
+
+      if Is_Protected_Type (Typ) then
+         Index_Typ := RE_Protected_Entry_Index;
+      else
+         Index_Typ := RE_Task_Entry_Index;
+      end if;
+
+      B_Decls := New_List;
+      Append_To (B_Decls,
+        Make_Object_Declaration (Loc,
+          Defining_Identifier => Index,
+          Object_Definition   => New_Reference_To (RTE (Index_Typ), Loc),
+          Expression          => Make_Integer_Literal (Loc, 0)));
+
+      B_Stmts := New_List;
+
+      --  Step 2: Generate a call to Set_Entry_Name for each entry and entry
+      --  family member.
+
+      Comp := First_Entity (Typ);
+      while Present (Comp) loop
+         if Ekind (Comp) = E_Entry then
+            Build_Entry_Name (Comp);
+
+         elsif Ekind (Comp) = E_Entry_Family then
+            Build_Entry_Family_Name (Comp);
+         end if;
+
+         Next_Entity (Comp);
+      end loop;
+
+      --  Step 3: Wrap the statements in a block
+
+      return
+        Make_Block_Statement (Loc,
+          Declarations => B_Decls,
+          Handled_Statement_Sequence =>
+            Make_Handled_Sequence_Of_Statements (Loc,
+              Statements => B_Stmts));
+   end Build_Entry_Names;
+
    ---------------------------
    -- Build_Parameter_Block --
    ---------------------------
@@ -1134,19 +1668,15 @@ package body Exp_Ch9 is
             --  Generate:
             --    type Ann is access all <actual-type>
 
-            Comp_Nam :=
-              Make_Defining_Identifier (Loc, New_Internal_Name ('A'));
+            Comp_Nam := Make_Temporary (Loc, 'A');
 
             Append_To (Decls,
               Make_Full_Type_Declaration (Loc,
-                Defining_Identifier =>
-                  Comp_Nam,
-                Type_Definition =>
+                Defining_Identifier => Comp_Nam,
+                Type_Definition     =>
                   Make_Access_To_Object_Definition (Loc,
-                    All_Present =>
-                      True,
-                    Constant_Present =>
-                      Ekind (Formal) = E_In_Parameter,
+                    All_Present        => True,
+                    Constant_Present   => Ekind (Formal) = E_In_Parameter,
                     Subtype_Indication =>
                       New_Reference_To (Etype (Actual), Loc))));
 
@@ -1171,8 +1701,7 @@ package body Exp_Ch9 is
          Next_Formal_With_Extras (Formal);
       end loop;
 
-      Rec_Nam :=
-        Make_Defining_Identifier (Loc, New_Internal_Name ('P'));
+      Rec_Nam := Make_Temporary (Loc, 'P');
 
       if Has_Comp then
 
@@ -1211,144 +1740,468 @@ package body Exp_Ch9 is
       return Rec_Nam;
    end Build_Parameter_Block;
 
-   ------------------------
-   -- Build_Wrapper_Body --
-   ------------------------
+   --------------------------------------
+   -- Build_Renamed_Formal_Declaration --
+   --------------------------------------
 
-   function Build_Wrapper_Body
-     (Loc      : Source_Ptr;
-      Proc_Nam : Entity_Id;
-      Obj_Typ  : Entity_Id;
-      Formals  : List_Id) return Node_Id
+   function Build_Renamed_Formal_Declaration
+     (New_F          : Entity_Id;
+      Formal         : Entity_Id;
+      Comp           : Entity_Id;
+      Renamed_Formal : Node_Id) return Node_Id
    is
-      Actuals      : List_Id := No_List;
-      Body_Spec    : Node_Id;
-      Conv_Id      : Node_Id;
-      First_Formal : Node_Id;
-      Formal       : Node_Id;
+      Loc  : constant Source_Ptr := Sloc (New_F);
+      Decl : Node_Id;
 
    begin
-      Body_Spec := Build_Wrapper_Spec (Loc, Proc_Nam, Obj_Typ, Formals);
+      --  If the formal is a tagged incomplete type, it is already passed
+      --  by reference, so it is sufficient to rename the pointer component
+      --  that corresponds to the actual. Otherwise we need to dereference
+      --  the pointer component to obtain the actual.
 
-      --  If we did not generate the specification do have nothing else to do
+      if Is_Incomplete_Type (Etype (Formal))
+        and then Is_Tagged_Type (Etype (Formal))
+      then
+         Decl :=
+           Make_Object_Renaming_Declaration (Loc,
+             Defining_Identifier => New_F,
+             Subtype_Mark        => New_Reference_To (Etype (Comp), Loc),
+             Name                => Renamed_Formal);
 
-      if Body_Spec = Empty then
-         return Empty;
+      else
+         Decl :=
+           Make_Object_Renaming_Declaration (Loc,
+             Defining_Identifier => New_F,
+             Subtype_Mark        => New_Reference_To (Etype (Formal), Loc),
+             Name                =>
+               Make_Explicit_Dereference (Loc, Renamed_Formal));
       end if;
 
-      --  Map formals to actuals. Use the list built for the wrapper spec,
-      --  skipping the object notation parameter.
+      return Decl;
+   end Build_Renamed_Formal_Declaration;
 
-      First_Formal := First (Parameter_Specifications (Body_Spec));
+   -----------------------
+   -- Build_PPC_Wrapper --
+   -----------------------
 
-      Formal := First_Formal;
-      Next (Formal);
+   procedure Build_PPC_Wrapper (E : Entity_Id; Decl : Node_Id) is
+      Loc        : constant Source_Ptr := Sloc (E);
+      Synch_Type : constant Entity_Id := Scope (E);
 
-      if Present (Formal) then
-         Actuals := New_List;
+      Wrapper_Id : constant Entity_Id :=
+                     Make_Defining_Identifier (Loc,
+                       Chars => New_External_Name (Chars (E), 'E'));
+      --  the wrapper procedure name
 
-         while Present (Formal) loop
-            Append_To (Actuals,
-              Make_Identifier (Loc, Chars =>
-                Chars (Defining_Identifier (Formal))));
+      Wrapper_Body : Node_Id;
 
-            Next (Formal);
+      Synch_Id : constant Entity_Id :=
+                   Make_Defining_Identifier (Loc,
+                     Chars => New_External_Name (Chars (Scope (E)), 'A'));
+      --  The parameter that designates the synchronized object in the call
+
+      Actuals : constant List_Id := New_List;
+      --  The actuals in the entry call
+
+      Decls : constant List_Id := New_List;
+
+      Entry_Call : Node_Id;
+      Entry_Name : Node_Id;
+
+      Specs : List_Id;
+      --  The specification of the wrapper procedure
+
+   begin
+
+      --  Only build the wrapper if entry has pre/postconditions.
+      --  Should this be done unconditionally instead ???
+
+      declare
+         P : Node_Id;
+
+      begin
+         P := Spec_PPC_List (Contract (E));
+         if No (P) then
+            return;
+         end if;
+
+         --  Transfer ppc pragmas to the declarations of the wrapper
+
+         while Present (P) loop
+            if Pragma_Name (P) = Name_Precondition
+              or else Pragma_Name (P) = Name_Postcondition
+            then
+               Append (Relocate_Node (P), Decls);
+               Set_Analyzed (Last (Decls), False);
+            end if;
+
+            P := Next_Pragma (P);
          end loop;
+      end;
+
+      --  First formal is synchronized object
+
+      Specs := New_List (
+        Make_Parameter_Specification (Loc,
+          Defining_Identifier => Synch_Id,
+          Out_Present         =>  True,
+          In_Present          =>  True,
+          Parameter_Type      => New_Occurrence_Of (Scope (E), Loc)));
+
+      Entry_Name :=
+        Make_Selected_Component (Loc,
+          Prefix        => New_Occurrence_Of (Synch_Id, Loc),
+          Selector_Name => New_Occurrence_Of (E, Loc));
+
+      --  If entity is entry family, second formal is the corresponding index,
+      --  and entry name is an indexed component.
+
+      if Ekind (E) = E_Entry_Family then
+         declare
+            Index : constant Entity_Id :=
+                      Make_Defining_Identifier (Loc, Name_I);
+         begin
+            Append_To (Specs,
+              Make_Parameter_Specification (Loc,
+                Defining_Identifier => Index,
+                Parameter_Type      =>
+                  New_Occurrence_Of (Entry_Index_Type (E), Loc)));
+
+            Entry_Name :=
+              Make_Indexed_Component (Loc,
+                Prefix      => Entry_Name,
+                Expressions => New_List (New_Occurrence_Of (Index, Loc)));
+         end;
       end if;
 
-      --  An access-to-variable first parameter will require an explicit
-      --  dereference in the unchecked conversion. This case occurs when
-      --  a protected entry wrapper must override an interface-level
-      --  procedure with interface access as first parameter.
+      Entry_Call :=
+        Make_Procedure_Call_Statement (Loc,
+          Name                   => Entry_Name,
+          Parameter_Associations => Actuals);
 
-      --     SubprgName (O.all).Proc_Nam (Formal_1 .. Formal_N)
+      --  Now add formals that match those of the entry, and build actuals for
+      --  the nested entry call.
 
-      if Nkind (Parameter_Type (First_Formal)) = N_Access_Definition then
-         Conv_Id :=
-           Make_Explicit_Dereference (Loc,
-             Prefix =>
-               Make_Identifier (Loc, Chars => Name_uO));
-      else
-         Conv_Id :=
-           Make_Identifier (Loc, Chars => Name_uO);
+      declare
+         Form      : Entity_Id;
+         New_Form  : Entity_Id;
+         Parm_Spec : Node_Id;
+
+      begin
+         Form := First_Formal (E);
+         while Present (Form) loop
+            New_Form := Make_Defining_Identifier (Loc, Chars (Form));
+            Parm_Spec :=
+              Make_Parameter_Specification (Loc,
+                Defining_Identifier => New_Form,
+                Out_Present         => Out_Present (Parent (Form)),
+                In_Present          => In_Present  (Parent (Form)),
+                Parameter_Type      => New_Occurrence_Of (Etype (Form), Loc));
+
+            Append (Parm_Spec, Specs);
+            Append (New_Occurrence_Of (New_Form, Loc), Actuals);
+            Next_Formal (Form);
+         end loop;
+      end;
+
+      --  Add renaming declarations for the discriminants of the enclosing
+      --  type, which may be visible in the preconditions.
+
+      if Has_Discriminants (Synch_Type) then
+         declare
+            D : Entity_Id;
+            Decl : Node_Id;
+
+         begin
+            D := First_Discriminant (Synch_Type);
+            while Present (D) loop
+               Decl :=
+                 Make_Object_Renaming_Declaration (Loc,
+                   Defining_Identifier =>
+                     Make_Defining_Identifier (Loc, Chars (D)),
+                   Subtype_Mark        => New_Reference_To (Etype (D), Loc),
+                   Name                =>
+                     Make_Selected_Component (Loc,
+                       Prefix        => New_Reference_To (Synch_Id, Loc),
+                       Selector_Name => Make_Identifier (Loc, Chars (D))));
+               Prepend (Decl, Decls);
+               Next_Discriminant (D);
+            end loop;
+         end;
       end if;
 
-      if Ekind (Proc_Nam) = E_Function then
-         return
-           Make_Subprogram_Body (Loc,
-             Specification => Body_Spec,
-             Declarations  => Empty_List,
-             Handled_Statement_Sequence =>
-               Make_Handled_Sequence_Of_Statements (Loc,
-                 Statements =>
-                   New_List (
-                     Make_Simple_Return_Statement (Loc,
-                        Make_Function_Call (Loc,
-                          Name =>
-                            Make_Selected_Component (Loc,
-                              Prefix =>
-                                Unchecked_Convert_To (
-                                  Corresponding_Concurrent_Type (Obj_Typ),
-                                  Conv_Id),
-                              Selector_Name =>
-                                New_Reference_To (Proc_Nam, Loc)),
-                          Parameter_Associations => Actuals)))));
+      Set_PPC_Wrapper (E, Wrapper_Id);
+      Wrapper_Body :=
+        Make_Subprogram_Body (Loc,
+          Specification              =>
+            Make_Procedure_Specification (Loc,
+              Defining_Unit_Name       => Wrapper_Id,
+              Parameter_Specifications => Specs),
+          Declarations               => Decls,
+          Handled_Statement_Sequence =>
+            Make_Handled_Sequence_Of_Statements (Loc,
+              Statements => New_List (Entry_Call)));
+
+      --  The wrapper body is analyzed when the enclosing type is frozen
+
+      Append_Freeze_Action (Defining_Entity (Decl), Wrapper_Body);
+   end Build_PPC_Wrapper;
+
+   --------------------------
+   -- Build_Wrapper_Bodies --
+   --------------------------
+
+   procedure Build_Wrapper_Bodies
+     (Loc : Source_Ptr;
+      Typ : Entity_Id;
+      N   : Node_Id)
+   is
+      Rec_Typ : Entity_Id;
+
+      function Build_Wrapper_Body
+        (Loc     : Source_Ptr;
+         Subp_Id : Entity_Id;
+         Obj_Typ : Entity_Id;
+         Formals : List_Id) return Node_Id;
+      --  Ada 2005 (AI-345): Build the body that wraps a primitive operation
+      --  associated with a protected or task type. Subp_Id is the subprogram
+      --  name which will be wrapped. Obj_Typ is the type of the new formal
+      --  parameter which handles dispatching and object notation. Formals are
+      --  the original formals of Subp_Id which will be explicitly replicated.
+
+      ------------------------
+      -- Build_Wrapper_Body --
+      ------------------------
+
+      function Build_Wrapper_Body
+        (Loc     : Source_Ptr;
+         Subp_Id : Entity_Id;
+         Obj_Typ : Entity_Id;
+         Formals : List_Id) return Node_Id
+      is
+         Body_Spec : Node_Id;
+
+      begin
+         Body_Spec := Build_Wrapper_Spec (Subp_Id, Obj_Typ, Formals);
+
+         --  The subprogram is not overriding or is not a primitive declared
+         --  between two views.
+
+         if No (Body_Spec) then
+            return Empty;
+         end if;
+
+         declare
+            Actuals    : List_Id := No_List;
+            Conv_Id    : Node_Id;
+            First_Form : Node_Id;
+            Formal     : Node_Id;
+            Nam        : Node_Id;
+
+         begin
+            --  Map formals to actuals. Use the list built for the wrapper
+            --  spec, skipping the object notation parameter.
+
+            First_Form := First (Parameter_Specifications (Body_Spec));
+
+            Formal := First_Form;
+            Next (Formal);
+
+            if Present (Formal) then
+               Actuals := New_List;
+               while Present (Formal) loop
+                  Append_To (Actuals,
+                    Make_Identifier (Loc,
+                      Chars => Chars (Defining_Identifier (Formal))));
+                  Next (Formal);
+               end loop;
+            end if;
+
+            --  Special processing for primitives declared between a private
+            --  type and its completion: the wrapper needs a properly typed
+            --  parameter if the wrapped operation has a controlling first
+            --  parameter. Note that this might not be the case for a function
+            --  with a controlling result.
+
+            if Is_Private_Primitive_Subprogram (Subp_Id) then
+               if No (Actuals) then
+                  Actuals := New_List;
+               end if;
+
+               if Is_Controlling_Formal (First_Formal (Subp_Id)) then
+                  Prepend_To (Actuals,
+                    Unchecked_Convert_To
+                      (Corresponding_Concurrent_Type (Obj_Typ),
+                       Make_Identifier (Loc, Name_uO)));
+
+               else
+                  Prepend_To (Actuals,
+                    Make_Identifier (Loc,
+                      Chars => Chars (Defining_Identifier (First_Form))));
+               end if;
+
+               Nam := New_Reference_To (Subp_Id, Loc);
+            else
+               --  An access-to-variable object parameter requires an explicit
+               --  dereference in the unchecked conversion. This case occurs
+               --  when a protected entry wrapper must override an interface
+               --  level procedure with interface access as first parameter.
+
+               --     O.all.Subp_Id (Formal_1, ..., Formal_N)
+
+               if Nkind (Parameter_Type (First_Form)) =
+                    N_Access_Definition
+               then
+                  Conv_Id :=
+                    Make_Explicit_Dereference (Loc,
+                      Prefix => Make_Identifier (Loc, Name_uO));
+               else
+                  Conv_Id := Make_Identifier (Loc, Name_uO);
+               end if;
+
+               Nam :=
+                 Make_Selected_Component (Loc,
+                   Prefix        =>
+                     Unchecked_Convert_To
+                       (Corresponding_Concurrent_Type (Obj_Typ), Conv_Id),
+                   Selector_Name => New_Reference_To (Subp_Id, Loc));
+            end if;
+
+            --  Create the subprogram body. For a function, the call to the
+            --  actual subprogram has to be converted to the corresponding
+            --  record if it is a controlling result.
+
+            if Ekind (Subp_Id) = E_Function then
+               declare
+                  Res : Node_Id;
+
+               begin
+                  Res :=
+                     Make_Function_Call (Loc,
+                       Name                   => Nam,
+                       Parameter_Associations => Actuals);
+
+                  if Has_Controlling_Result (Subp_Id) then
+                     Res :=
+                       Unchecked_Convert_To
+                         (Corresponding_Record_Type (Etype (Subp_Id)), Res);
+                  end if;
+
+                  return
+                    Make_Subprogram_Body (Loc,
+                      Specification              => Body_Spec,
+                      Declarations               => Empty_List,
+                      Handled_Statement_Sequence =>
+                        Make_Handled_Sequence_Of_Statements (Loc,
+                          Statements => New_List (
+                            Make_Simple_Return_Statement (Loc, Res))));
+               end;
+
+            else
+               return
+                 Make_Subprogram_Body (Loc,
+                   Specification              => Body_Spec,
+                   Declarations               => Empty_List,
+                   Handled_Statement_Sequence =>
+                     Make_Handled_Sequence_Of_Statements (Loc,
+                       Statements => New_List (
+                         Make_Procedure_Call_Statement (Loc,
+                           Name                   => Nam,
+                           Parameter_Associations => Actuals))));
+            end if;
+         end;
+      end Build_Wrapper_Body;
+
+   --  Start of processing for Build_Wrapper_Bodies
+
+   begin
+      if Is_Concurrent_Type (Typ) then
+         Rec_Typ := Corresponding_Record_Type (Typ);
       else
-         return
-           Make_Subprogram_Body (Loc,
-             Specification => Body_Spec,
-             Declarations  => Empty_List,
-             Handled_Statement_Sequence =>
-               Make_Handled_Sequence_Of_Statements (Loc,
-                 Statements =>
-                   New_List (
-                     Make_Procedure_Call_Statement (Loc,
-                       Name =>
-                         Make_Selected_Component (Loc,
-                           Prefix =>
-                             Unchecked_Convert_To (
-                               Corresponding_Concurrent_Type (Obj_Typ),
-                               Conv_Id),
-                           Selector_Name =>
-                             New_Reference_To (Proc_Nam, Loc)),
-                       Parameter_Associations => Actuals))));
+         Rec_Typ := Typ;
+      end if;
+
+      --  Generate wrapper bodies for a concurrent type which implements an
+      --  interface.
+
+      if Present (Interfaces (Rec_Typ)) then
+         declare
+            Insert_Nod : Node_Id;
+            Prim       : Entity_Id;
+            Prim_Elmt  : Elmt_Id;
+            Prim_Decl  : Node_Id;
+            Subp       : Entity_Id;
+            Wrap_Body  : Node_Id;
+            Wrap_Id    : Entity_Id;
+
+         begin
+            Insert_Nod := N;
+
+            --  Examine all primitive operations of the corresponding record
+            --  type, looking for wrapper specs. Generate bodies in order to
+            --  complete them.
+
+            Prim_Elmt := First_Elmt (Primitive_Operations (Rec_Typ));
+            while Present (Prim_Elmt) loop
+               Prim := Node (Prim_Elmt);
+
+               if (Ekind (Prim) = E_Function
+                     or else Ekind (Prim) = E_Procedure)
+                 and then Is_Primitive_Wrapper (Prim)
+               then
+                  Subp := Wrapped_Entity (Prim);
+                  Prim_Decl := Parent (Parent (Prim));
+
+                  Wrap_Body :=
+                    Build_Wrapper_Body (Loc,
+                      Subp_Id => Subp,
+                      Obj_Typ => Rec_Typ,
+                      Formals => Parameter_Specifications (Parent (Subp)));
+                  Wrap_Id := Defining_Unit_Name (Specification (Wrap_Body));
+
+                  Set_Corresponding_Spec (Wrap_Body, Prim);
+                  Set_Corresponding_Body (Prim_Decl, Wrap_Id);
+
+                  Insert_After (Insert_Nod, Wrap_Body);
+                  Insert_Nod := Wrap_Body;
+
+                  Analyze (Wrap_Body);
+               end if;
+
+               Next_Elmt (Prim_Elmt);
+            end loop;
+         end;
       end if;
-   end Build_Wrapper_Body;
+   end Build_Wrapper_Bodies;
 
    ------------------------
    -- Build_Wrapper_Spec --
    ------------------------
 
    function Build_Wrapper_Spec
-     (Loc      : Source_Ptr;
-      Proc_Nam : Entity_Id;
-      Obj_Typ  : Entity_Id;
-      Formals  : List_Id) return Node_Id
+     (Subp_Id : Entity_Id;
+      Obj_Typ : Entity_Id;
+      Formals : List_Id) return Node_Id
    is
-      New_Name_Id : constant Entity_Id :=
-                      Make_Defining_Identifier (Loc, Chars (Proc_Nam));
-
-      First_Param        : Node_Id := Empty;
-      Iface              : Entity_Id;
-      Iface_Elmt         : Elmt_Id := No_Elmt;
-      New_Formals        : List_Id;
-      Obj_Param          : Node_Id;
-      Obj_Param_Typ      : Node_Id;
-      Iface_Prim_Op      : Entity_Id;
-      Iface_Prim_Op_Elmt : Elmt_Id;
+      Loc           : constant Source_Ptr := Sloc (Subp_Id);
+      First_Param   : Node_Id;
+      Iface         : Entity_Id;
+      Iface_Elmt    : Elmt_Id;
+      Iface_Op      : Entity_Id;
+      Iface_Op_Elmt : Elmt_Id;
 
       function Overriding_Possible
-        (Iface_Prim_Op : Entity_Id;
-         Proc_Nam      : Entity_Id) return Boolean;
-      --  Determine whether a primitive operation can be overridden by the
-      --  wrapper. Iface_Prim_Op is the candidate primitive operation of an
-      --  abstract interface type, Proc_Nam is the generated entry wrapper.
+        (Iface_Op : Entity_Id;
+         Wrapper  : Entity_Id) return Boolean;
+      --  Determine whether a primitive operation can be overridden by Wrapper.
+      --  Iface_Op is the candidate primitive operation of an interface type,
+      --  Wrapper is the generated entry wrapper.
 
-      function Replicate_Entry_Formals
+      function Replicate_Formals
         (Loc     : Source_Ptr;
          Formals : List_Id) return List_Id;
-      --  An explicit parameter replication is required due to the
-      --  Is_Entry_Formal flag being set for all the formals. The explicit
+      --  An explicit parameter replication is required due to the Is_Entry_
+      --  Formal flag being set for all the formals of an entry. The explicit
       --  replication removes the flag that would otherwise cause a different
       --  path of analysis.
 
@@ -1357,62 +2210,67 @@ package body Exp_Ch9 is
       -------------------------
 
       function Overriding_Possible
-        (Iface_Prim_Op : Entity_Id;
-         Proc_Nam      : Entity_Id) return Boolean
+        (Iface_Op : Entity_Id;
+         Wrapper  : Entity_Id) return Boolean
       is
-         Prim_Op_Spec  : constant Node_Id := Parent (Iface_Prim_Op);
-         Proc_Spec     : constant Node_Id := Parent (Proc_Nam);
-
-         Is_Access_To_Variable : Boolean;
-         Is_Out_Present        : Boolean;
+         Iface_Op_Spec : constant Node_Id := Parent (Iface_Op);
+         Wrapper_Spec  : constant Node_Id := Parent (Wrapper);
 
          function Type_Conformant_Parameters
-           (Prim_Op_Param_Specs : List_Id;
-            Proc_Param_Specs    : List_Id) return Boolean;
+           (Iface_Op_Params : List_Id;
+            Wrapper_Params  : List_Id) return Boolean;
          --  Determine whether the parameters of the generated entry wrapper
          --  and those of a primitive operation are type conformant. During
          --  this check, the first parameter of the primitive operation is
-         --  always skipped.
+         --  skipped if it is a controlling argument: protected functions
+         --  may have a controlling result.
 
          --------------------------------
          -- Type_Conformant_Parameters --
          --------------------------------
 
          function Type_Conformant_Parameters
-           (Prim_Op_Param_Specs : List_Id;
-            Proc_Param_Specs    : List_Id) return Boolean
+           (Iface_Op_Params : List_Id;
+            Wrapper_Params  : List_Id) return Boolean
          is
-            Prim_Op_Param : Node_Id;
-            Prim_Op_Typ   : Entity_Id;
-            Proc_Param    : Node_Id;
-            Proc_Typ      : Entity_Id;
+            Iface_Op_Param : Node_Id;
+            Iface_Op_Typ   : Entity_Id;
+            Wrapper_Param  : Node_Id;
+            Wrapper_Typ    : Entity_Id;
 
          begin
-            --  Skip the first parameter of the primitive operation
+            --  Skip the first (controlling) parameter of primitive operation
+
+            Iface_Op_Param := First (Iface_Op_Params);
+
+            if Present (First_Formal (Iface_Op))
+              and then Is_Controlling_Formal (First_Formal (Iface_Op))
+            then
+               Iface_Op_Param := Next (Iface_Op_Param);
+            end if;
 
-            Prim_Op_Param := Next (First (Prim_Op_Param_Specs));
-            Proc_Param    := First (Proc_Param_Specs);
-            while Present (Prim_Op_Param)
-              and then Present (Proc_Param)
+            Wrapper_Param  := First (Wrapper_Params);
+            while Present (Iface_Op_Param)
+              and then Present (Wrapper_Param)
             loop
-               Prim_Op_Typ := Find_Parameter_Type (Prim_Op_Param);
-               Proc_Typ    := Find_Parameter_Type (Proc_Param);
+               Iface_Op_Typ := Find_Parameter_Type (Iface_Op_Param);
+               Wrapper_Typ  := Find_Parameter_Type (Wrapper_Param);
 
                --  The two parameters must be mode conformant
 
                if not Conforming_Types
-                        (Prim_Op_Typ, Proc_Typ, Mode_Conformant)
+                        (Iface_Op_Typ, Wrapper_Typ, Mode_Conformant)
                then
                   return False;
                end if;
 
-               Next (Prim_Op_Param);
-               Next (Proc_Param);
+               Next (Iface_Op_Param);
+               Next (Wrapper_Param);
             end loop;
 
             --  One of the lists is longer than the other
 
-            if Present (Prim_Op_Param) or else Present (Proc_Param) then
+            if Present (Iface_Op_Param) or else Present (Wrapper_Param) then
                return False;
             end if;
 
@@ -1422,47 +2280,41 @@ package body Exp_Ch9 is
       --  Start of processing for Overriding_Possible
 
       begin
-         if Chars (Iface_Prim_Op) /= Chars (Proc_Nam) then
+         if Chars (Iface_Op) /= Chars (Wrapper) then
             return False;
          end if;
 
-         --  Special check for protected procedures: If an inherited subprogram
-         --  is implemented by a protected procedure or an entry, then the
-         --  first parameter of the inherited subprogram shall be of mode OUT
-         --  or IN OUT, or an access-to-variable parameter.
-
-         if Ekind (Iface_Prim_Op) = E_Procedure then
-
-            Is_Out_Present :=
-              Present (Parameter_Specifications (Prim_Op_Spec))
-                and then
-              Out_Present (First (Parameter_Specifications (Prim_Op_Spec)));
+         --  If an inherited subprogram is implemented by a protected procedure
+         --  or an entry, then the first parameter of the inherited subprogram
+         --  shall be of mode OUT or IN OUT, or access-to-variable parameter.
 
-            Is_Access_To_Variable :=
-              Present (Parameter_Specifications (Prim_Op_Spec))
-                and then
-              Nkind (Parameter_Type
-                      (First
-                        (Parameter_Specifications (Prim_Op_Spec)))) =
-                                                          N_Access_Definition;
-
-            if not Is_Out_Present
-              and then not Is_Access_To_Variable
-            then
-               return False;
-            end if;
+         if Ekind (Iface_Op) = E_Procedure
+           and then Present (Parameter_Specifications (Iface_Op_Spec))
+         then
+            declare
+               Obj_Param : constant Node_Id :=
+                             First (Parameter_Specifications (Iface_Op_Spec));
+            begin
+               if not Out_Present (Obj_Param)
+                 and then Nkind (Parameter_Type (Obj_Param)) /=
+                                                         N_Access_Definition
+               then
+                  return False;
+               end if;
+            end;
          end if;
 
-         return Type_Conformant_Parameters (
-           Parameter_Specifications (Prim_Op_Spec),
-           Parameter_Specifications (Proc_Spec));
+         return
+           Type_Conformant_Parameters (
+             Parameter_Specifications (Iface_Op_Spec),
+             Parameter_Specifications (Wrapper_Spec));
       end Overriding_Possible;
 
-      -----------------------------
-      -- Replicate_Entry_Formals --
-      -----------------------------
+      -----------------------
+      -- Replicate_Formals --
+      -----------------------
 
-      function Replicate_Entry_Formals
+      function Replicate_Formals
         (Loc     : Source_Ptr;
          Formals : List_Id) return List_Id
       is
@@ -1472,6 +2324,16 @@ package body Exp_Ch9 is
 
       begin
          Formal := First (Formals);
+
+         --  Skip the object parameter when dealing with primitives declared
+         --  between two views.
+
+         if Is_Private_Primitive_Subprogram (Subp_Id)
+           and then not Has_Controlling_Result (Subp_Id)
+         then
+            Formal := Next (Formal);
+         end if;
+
          while Present (Formal) loop
 
             --  Create an explicit copy of the entry parameter
@@ -1505,166 +2367,295 @@ package body Exp_Ch9 is
          end loop;
 
          return New_Formals;
-      end Replicate_Entry_Formals;
+      end Replicate_Formals;
 
    --  Start of processing for Build_Wrapper_Spec
 
    begin
-      --  The mode is determined by the first parameter of the interface-level
-      --  procedure that the current entry is trying to override.
-
-      pragma Assert (Is_Non_Empty_List (Abstract_Interface_List (Obj_Typ)));
-
-      --  We must examine all the protected operations of the implemented
-      --  interfaces in order to discover a possible overriding candidate.
-
-      Iface := Etype (First (Abstract_Interface_List (Obj_Typ)));
-
-      Examine_Parents : loop
-         if Present (Primitive_Operations (Iface)) then
-            Iface_Prim_Op_Elmt := First_Elmt (Primitive_Operations (Iface));
-            while Present (Iface_Prim_Op_Elmt) loop
-               Iface_Prim_Op := Node (Iface_Prim_Op_Elmt);
-
-               if not Is_Predefined_Dispatching_Operation (Iface_Prim_Op) then
-                  while Present (Alias (Iface_Prim_Op)) loop
-                     Iface_Prim_Op := Alias (Iface_Prim_Op);
-                  end loop;
-
-                  --  The current primitive operation can be overridden by the
-                  --  generated entry wrapper.
-
-                  if Overriding_Possible (Iface_Prim_Op, Proc_Nam) then
-                     First_Param := First  (Parameter_Specifications
-                                             (Parent (Iface_Prim_Op)));
+      --  There is no point in building wrappers for non-tagged concurrent
+      --  types.
 
-                     goto Found;
-                  end if;
-               end if;
+      pragma Assert (Is_Tagged_Type (Obj_Typ));
 
-               Next_Elmt (Iface_Prim_Op_Elmt);
-            end loop;
-         end if;
+      --  An entry or a protected procedure can override a routine where the
+      --  controlling formal is either IN OUT, OUT or is of access-to-variable
+      --  type. Since the wrapper must have the exact same signature as that of
+      --  the overridden subprogram, we try to find the overriding candidate
+      --  and use its controlling formal.
 
-         exit Examine_Parents when Etype (Iface) = Iface;
+      First_Param := Empty;
 
-         Iface := Etype (Iface);
-      end loop Examine_Parents;
+      --  Check every implemented interface
 
-      if Present (Abstract_Interfaces
-                   (Corresponding_Record_Type (Scope (Proc_Nam))))
-      then
-         Iface_Elmt := First_Elmt
-                         (Abstract_Interfaces
-                           (Corresponding_Record_Type (Scope (Proc_Nam))));
-         Examine_Interfaces : while Present (Iface_Elmt) loop
+      if Present (Interfaces (Obj_Typ)) then
+         Iface_Elmt := First_Elmt (Interfaces (Obj_Typ));
+         Search : while Present (Iface_Elmt) loop
             Iface := Node (Iface_Elmt);
 
+            --  Check every interface primitive
+
             if Present (Primitive_Operations (Iface)) then
-               Iface_Prim_Op_Elmt := First_Elmt (Primitive_Operations (Iface));
-               while Present (Iface_Prim_Op_Elmt) loop
-                  Iface_Prim_Op := Node (Iface_Prim_Op_Elmt);
+               Iface_Op_Elmt := First_Elmt (Primitive_Operations (Iface));
+               while Present (Iface_Op_Elmt) loop
+                  Iface_Op := Node (Iface_Op_Elmt);
 
-                  if not Is_Predefined_Dispatching_Operation
-                           (Iface_Prim_Op)
-                  then
-                     while Present (Alias (Iface_Prim_Op)) loop
-                        Iface_Prim_Op := Alias (Iface_Prim_Op);
-                     end loop;
+                  --  Ignore predefined primitives
+
+                  if not Is_Predefined_Dispatching_Operation (Iface_Op) then
+                     Iface_Op := Ultimate_Alias (Iface_Op);
 
                      --  The current primitive operation can be overridden by
                      --  the generated entry wrapper.
 
-                     if Overriding_Possible (Iface_Prim_Op, Proc_Nam) then
-                        First_Param := First (Parameter_Specifications
-                                               (Parent (Iface_Prim_Op)));
+                     if Overriding_Possible (Iface_Op, Subp_Id) then
+                        First_Param :=
+                          First (Parameter_Specifications (Parent (Iface_Op)));
 
-                        goto Found;
+                        exit Search;
                      end if;
                   end if;
 
-                  Next_Elmt (Iface_Prim_Op_Elmt);
+                  Next_Elmt (Iface_Op_Elmt);
                end loop;
             end if;
 
             Next_Elmt (Iface_Elmt);
-         end loop Examine_Interfaces;
+         end loop Search;
+      end if;
+
+      --  Ada 2012 (AI05-0090-1): If no interface primitive is covered by
+      --  this subprogram and this is not a primitive declared between two
+      --  views then force the generation of a wrapper. As an optimization,
+      --  previous versions of the frontend avoid generating the wrapper;
+      --  however, the wrapper facilitates locating and reporting an error
+      --  when a duplicate declaration is found later. See example in
+      --  AI05-0090-1.
+
+      if No (First_Param)
+        and then not Is_Private_Primitive_Subprogram (Subp_Id)
+      then
+         if Is_Task_Type
+              (Corresponding_Concurrent_Type (Obj_Typ))
+         then
+            First_Param :=
+              Make_Parameter_Specification (Loc,
+                Defining_Identifier => Make_Defining_Identifier (Loc, Name_uO),
+                In_Present          => True,
+                Out_Present         => False,
+                Parameter_Type      => New_Reference_To (Obj_Typ, Loc));
+
+         --  For entries and procedures of protected types the mode of
+         --  the controlling argument must be in-out.
+
+         else
+            First_Param :=
+              Make_Parameter_Specification (Loc,
+                Defining_Identifier =>
+                  Make_Defining_Identifier (Loc,
+                    Chars => Name_uO),
+                In_Present     => True,
+                Out_Present    => (Ekind (Subp_Id) /= E_Function),
+                Parameter_Type => New_Reference_To (Obj_Typ, Loc));
+         end if;
       end if;
 
-      --  Return if no interface primitive can be overridden
+      declare
+         Wrapper_Id    : constant Entity_Id :=
+                           Make_Defining_Identifier (Loc, Chars (Subp_Id));
+         New_Formals   : List_Id;
+         Obj_Param     : Node_Id;
+         Obj_Param_Typ : Entity_Id;
+
+      begin
+         --  Minimum decoration is needed to catch the entity in
+         --  Sem_Ch6.Override_Dispatching_Operation.
 
-      return Empty;
+         if Ekind (Subp_Id) = E_Function then
+            Set_Ekind (Wrapper_Id, E_Function);
+         else
+            Set_Ekind (Wrapper_Id, E_Procedure);
+         end if;
 
-      <<Found>>
+         Set_Is_Primitive_Wrapper (Wrapper_Id);
+         Set_Wrapped_Entity       (Wrapper_Id, Subp_Id);
+         Set_Is_Private_Primitive (Wrapper_Id,
+           Is_Private_Primitive_Subprogram (Subp_Id));
 
-      New_Formals := Replicate_Entry_Formals (Loc, Formals);
+         --  Process the formals
 
-      --  ??? Certain source packages contain protected or task types that do
-      --  not implement any interfaces and are compiled with the -gnat05
-      --  switch.  In this case, a default first parameter is created.
+         New_Formals := Replicate_Formals (Loc, Formals);
 
-      --  If the interface operation has an access parameter, create a copy
-      --  of it, with the same null exclusion indicator if present.
+         --  A function with a controlling result and no first controlling
+         --  formal needs no additional parameter.
 
-      if Present (First_Param) then
-         if Nkind (Parameter_Type (First_Param)) = N_Access_Definition then
-            Obj_Param_Typ :=
-              Make_Access_Definition (Loc,
-                Subtype_Mark =>
-                  New_Reference_To (Obj_Typ, Loc));
-            Set_Null_Exclusion_Present (Obj_Param_Typ,
-               Null_Exclusion_Present (Parameter_Type (First_Param)));
+         if Has_Controlling_Result (Subp_Id)
+           and then
+             (No (First_Formal (Subp_Id))
+               or else not Is_Controlling_Formal (First_Formal (Subp_Id)))
+         then
+            null;
+
+         --  Routine Subp_Id has been found to override an interface primitive.
+         --  If the interface operation has an access parameter, create a copy
+         --  of it, with the same null exclusion indicator if present.
+
+         elsif Present (First_Param) then
+            if Nkind (Parameter_Type (First_Param)) = N_Access_Definition then
+               Obj_Param_Typ :=
+                 Make_Access_Definition (Loc,
+                   Subtype_Mark =>
+                     New_Reference_To (Obj_Typ, Loc));
+               Set_Null_Exclusion_Present (Obj_Param_Typ,
+                 Null_Exclusion_Present (Parameter_Type (First_Param)));
+
+            else
+               Obj_Param_Typ := New_Reference_To (Obj_Typ, Loc);
+            end if;
+
+            Obj_Param :=
+              Make_Parameter_Specification (Loc,
+                Defining_Identifier =>
+                  Make_Defining_Identifier (Loc,
+                    Chars => Name_uO),
+                In_Present          => In_Present  (First_Param),
+                Out_Present         => Out_Present (First_Param),
+                Parameter_Type      => Obj_Param_Typ);
+
+            Prepend_To (New_Formals, Obj_Param);
+
+         --  If we are dealing with a primitive declared between two views,
+         --  implemented by a synchronized operation, we need to create
+         --  a default parameter. The mode of the parameter must match that
+         --  of the primitive operation.
 
          else
-            Obj_Param_Typ := New_Reference_To (Obj_Typ, Loc);
+            pragma Assert (Is_Private_Primitive_Subprogram (Subp_Id));
+            Obj_Param :=
+              Make_Parameter_Specification (Loc,
+                Defining_Identifier =>
+                  Make_Defining_Identifier (Loc, Name_uO),
+                In_Present  => In_Present (Parent (First_Entity (Subp_Id))),
+                Out_Present => Ekind (Subp_Id) /= E_Function,
+                  Parameter_Type => New_Reference_To (Obj_Typ, Loc));
+            Prepend_To (New_Formals, Obj_Param);
          end if;
 
-         Obj_Param :=
-           Make_Parameter_Specification (Loc,
-             Defining_Identifier =>
-               Make_Defining_Identifier (Loc, Name_uO),
-             In_Present  => In_Present  (First_Param),
-             Out_Present => Out_Present (First_Param),
-             Parameter_Type => Obj_Param_Typ);
+         --  Build the final spec. If it is a function with a controlling
+         --  result, it is a primitive operation of the corresponding
+         --  record type, so mark the spec accordingly.
 
-      else
-         Obj_Param :=
-           Make_Parameter_Specification (Loc,
-             Defining_Identifier =>
-               Make_Defining_Identifier (Loc, Name_uO),
-             In_Present  => True,
-             Out_Present => True,
-               Parameter_Type => New_Reference_To (Obj_Typ, Loc));
-      end if;
+         if Ekind (Subp_Id) = E_Function then
+            declare
+               Res_Def : Node_Id;
+
+            begin
+               if Has_Controlling_Result (Subp_Id) then
+                  Res_Def :=
+                    New_Occurrence_Of
+                      (Corresponding_Record_Type (Etype (Subp_Id)), Loc);
+               else
+                  Res_Def := New_Copy (Result_Definition (Parent (Subp_Id)));
+               end if;
+
+               return
+                 Make_Function_Specification (Loc,
+                   Defining_Unit_Name       => Wrapper_Id,
+                   Parameter_Specifications => New_Formals,
+                   Result_Definition        => Res_Def);
+            end;
+         else
+            return
+              Make_Procedure_Specification (Loc,
+                Defining_Unit_Name       => Wrapper_Id,
+                Parameter_Specifications => New_Formals);
+         end if;
+      end;
+   end Build_Wrapper_Spec;
 
-      Prepend_To (New_Formals, Obj_Param);
+   -------------------------
+   -- Build_Wrapper_Specs --
+   -------------------------
 
-      --  Minimum decoration needed to catch the entity in
-      --  Sem_Ch6.Override_Dispatching_Operation
+   procedure Build_Wrapper_Specs
+     (Loc : Source_Ptr;
+      Typ : Entity_Id;
+      N   : in out Node_Id)
+   is
+      Def     : Node_Id;
+      Rec_Typ : Entity_Id;
+      procedure Scan_Declarations (L : List_Id);
+      --  Common processing for visible and private declarations
+      --  of a protected type.
 
-      if Ekind (Proc_Nam) = E_Procedure
-        or else Ekind (Proc_Nam) = E_Entry
-      then
-         Set_Ekind                (New_Name_Id, E_Procedure);
-         Set_Is_Primitive_Wrapper (New_Name_Id);
-         Set_Wrapped_Entity       (New_Name_Id, Proc_Nam);
+      procedure Scan_Declarations (L : List_Id) is
+         Decl      : Node_Id;
+         Wrap_Decl : Node_Id;
+         Wrap_Spec : Node_Id;
 
-         return
-           Make_Procedure_Specification (Loc,
-             Defining_Unit_Name => New_Name_Id,
-             Parameter_Specifications => New_Formals);
+      begin
+         if No (L) then
+            return;
+         end if;
 
-      else pragma Assert (Ekind (Proc_Nam) = E_Function);
-         Set_Ekind (New_Name_Id, E_Function);
+         Decl := First (L);
+         while Present (Decl) loop
+            Wrap_Spec := Empty;
 
-         return
-           Make_Function_Specification (Loc,
-             Defining_Unit_Name => New_Name_Id,
-             Parameter_Specifications => New_Formals,
-             Result_Definition =>
-               New_Copy (Result_Definition (Parent (Proc_Nam))));
+            if Nkind (Decl) = N_Entry_Declaration
+              and then Ekind (Defining_Identifier (Decl)) = E_Entry
+            then
+               Wrap_Spec :=
+                 Build_Wrapper_Spec
+                   (Subp_Id => Defining_Identifier (Decl),
+                    Obj_Typ => Rec_Typ,
+                    Formals => Parameter_Specifications (Decl));
+
+            elsif Nkind (Decl) = N_Subprogram_Declaration then
+               Wrap_Spec :=
+                 Build_Wrapper_Spec
+                   (Subp_Id => Defining_Unit_Name (Specification (Decl)),
+                    Obj_Typ => Rec_Typ,
+                    Formals =>
+                      Parameter_Specifications (Specification (Decl)));
+            end if;
+
+            if Present (Wrap_Spec) then
+               Wrap_Decl :=
+                 Make_Subprogram_Declaration (Loc,
+                   Specification => Wrap_Spec);
+
+               Insert_After (N, Wrap_Decl);
+               N := Wrap_Decl;
+
+               Analyze (Wrap_Decl);
+            end if;
+
+            Next (Decl);
+         end loop;
+      end Scan_Declarations;
+
+      --  start of processing for Build_Wrapper_Specs
+
+   begin
+      if Is_Protected_Type (Typ) then
+         Def := Protected_Definition (Parent (Typ));
+      else pragma Assert (Is_Task_Type (Typ));
+         Def := Task_Definition (Parent (Typ));
       end if;
-   end Build_Wrapper_Spec;
+
+      Rec_Typ := Corresponding_Record_Type (Typ);
+
+      --  Generate wrapper specs for a concurrent type which implements an
+      --  interface. Operations in both the visible and private parts may
+      --  implement progenitor operations.
+
+      if Present (Interfaces (Rec_Typ))
+        and then Present (Def)
+      then
+         Scan_Declarations (Visible_Declarations (Def));
+         Scan_Declarations (Private_Declarations (Def));
+      end if;
+   end Build_Wrapper_Specs;
 
    ---------------------------
    -- Build_Find_Body_Index --
@@ -1720,10 +2711,10 @@ package body Exp_Ch9 is
 
          Cond :=
            Make_Op_Le (Loc,
-             Left_Opnd => Make_Identifier (Loc, Name_uE),
+             Left_Opnd  => Make_Identifier (Loc, Name_uE),
              Right_Opnd => Siz);
 
-         --  Map entry queue indices in the range of the current family
+         --  Map entry queue indexes in the range of the current family
          --  into the current index, that designates the entry body.
 
          if No (If_St) then
@@ -1809,12 +2800,10 @@ package body Exp_Ch9 is
          Add_Object_Pointer (Loc, Typ, Decls);
 
          while Present (Ent) loop
-
             if Ekind (Ent) = E_Entry then
                Add_If_Clause (Make_Integer_Literal (Loc, 1));
 
             elsif Ekind (Ent) = E_Entry_Family then
-
                E_Typ := Etype (Discrete_Subtype_Definition (Parent (Ent)));
                Hi := Convert_Discriminant_Ref (Type_High_Bound (E_Typ));
                Lo := Convert_Discriminant_Ref (Type_Low_Bound  (E_Typ));
@@ -1886,89 +2875,212 @@ package body Exp_Ch9 is
    -- Build_Master_Entity --
    -------------------------
 
-   procedure Build_Master_Entity (E : Entity_Id) is
-      Loc  : constant Source_Ptr := Sloc (E);
-      P    : Node_Id;
-      Decl : Node_Id;
-      S    : Entity_Id;
+   procedure Build_Master_Entity (Obj_Or_Typ : Entity_Id) is
+      Loc        : constant Source_Ptr := Sloc (Obj_Or_Typ);
+      Context    : Node_Id;
+      Context_Id : Entity_Id;
+      Decl       : Node_Id;
+      Decls      : List_Id;
+      Par        : Node_Id;
 
    begin
-      S := Scope (E);
+      if Is_Itype (Obj_Or_Typ) then
+         Par := Associated_Node_For_Itype (Obj_Or_Typ);
+      else
+         Par := Parent (Obj_Or_Typ);
+      end if;
 
-      --  Ada 2005 (AI-287): Do not set/get the has_master_entity reminder
-      --  in internal scopes, unless present already.. Required for nested
-      --  limited aggregates, where the expansion of task components may
-      --  generate inner blocks. If the block is the rewriting of a call
-      --  this is valid master.
+      --  When creating a master for a record component which is either a task
+      --  or access-to-task, the enclosing record is the master scope and the
+      --  proper insertion point is the component list.
 
-      if Ada_Version >= Ada_05 then
-         while Is_Internal (S) loop
-            if Nkind (Parent (S)) = N_Block_Statement
-              and then
-                Nkind (Original_Node (Parent (S))) = N_Procedure_Call_Statement
-            then
-               exit;
-            else
-               S := Scope (S);
-            end if;
-         end loop;
+      if Is_Record_Type (Current_Scope) then
+         Context    := Par;
+         Context_Id := Current_Scope;
+         Decls      := List_Containing (Context);
+
+      --  Default case for object declarations and access types. Note that the
+      --  context is updated to the nearest enclosing body, block, package or
+      --  return statement.
+
+      else
+         Find_Enclosing_Context (Par, Context, Context_Id, Decls);
       end if;
 
-      --  Nothing to do if we already built a master entity for this scope
-      --  or if there is no task hierarchy.
+      --  Do not create a master if one already exists or there is no task
+      --  hierarchy.
 
-      if Has_Master_Entity (S)
+      if Has_Master_Entity (Context_Id)
         or else Restriction_Active (No_Task_Hierarchy)
       then
          return;
       end if;
 
-      --  Otherwise first build the master entity
+      --  Create a master, generate:
       --    _Master : constant Master_Id := Current_Master.all;
-      --  and insert it just before the current declaration
 
       Decl :=
         Make_Object_Declaration (Loc,
           Defining_Identifier =>
             Make_Defining_Identifier (Loc, Name_uMaster),
-          Constant_Present => True,
-          Object_Definition => New_Reference_To (RTE (RE_Master_Id), Loc),
-          Expression =>
+          Constant_Present    => True,
+          Object_Definition   => New_Reference_To (RTE (RE_Master_Id), Loc),
+          Expression          =>
             Make_Explicit_Dereference (Loc,
               New_Reference_To (RTE (RE_Current_Master), Loc)));
 
-      P := Parent (E);
-      Insert_Before (P, Decl);
-      Analyze (Decl);
+      --  The master is inserted at the start of the declarative list of the
+      --  context.
+
+      Prepend_To (Decls, Decl);
 
-      --  Ada 2005 (AI-287): Set the has_master_entity reminder in the
-      --  non-internal scope selected above.
+      --  In certain cases where transient scopes are involved, the immediate
+      --  scope is not always the proper master scope. Ensure that the master
+      --  declaration and entity appear in the same context.
 
-      if Ada_Version >= Ada_05 then
-         Set_Has_Master_Entity (S);
+      if Context_Id /= Current_Scope then
+         Push_Scope (Context_Id);
+         Analyze (Decl);
+         Pop_Scope;
       else
-         Set_Has_Master_Entity (Scope (E));
+         Analyze (Decl);
       end if;
 
-      --  Now mark the containing scope as a task master
+      --  Mark the enclosing scope and its associated construct as being task
+      --  masters.
+
+      Set_Has_Master_Entity (Context_Id);
+
+      while Present (Context)
+        and then Nkind (Context) /= N_Compilation_Unit
+      loop
+         if Nkind_In (Context, N_Block_Statement,
+                               N_Subprogram_Body,
+                               N_Task_Body)
+         then
+            Set_Is_Task_Master (Context);
+            exit;
 
-      while Nkind (P) /= N_Compilation_Unit loop
-         P := Parent (P);
+         elsif Nkind (Parent (Context)) = N_Subunit then
+            Context := Corresponding_Stub (Parent (Context));
+         end if;
+
+         Context := Parent (Context);
+      end loop;
+   end Build_Master_Entity;
+
+   ---------------------------
+   -- Build_Master_Renaming --
+   ---------------------------
+
+   procedure Build_Master_Renaming
+     (Ptr_Typ : Entity_Id;
+      Ins_Nod : Node_Id := Empty)
+   is
+      Loc         : constant Source_Ptr := Sloc (Ptr_Typ);
+      Context     : Node_Id;
+      Master_Decl : Node_Id;
+      Master_Id   : Entity_Id;
+
+   begin
+      --  Nothing to do if there is no task hierarchy
+
+      if Restriction_Active (No_Task_Hierarchy) then
+         return;
+      end if;
+
+      --  Determine the proper context to insert the master renaming
+
+      if Present (Ins_Nod) then
+         Context := Ins_Nod;
+      elsif Is_Itype (Ptr_Typ) then
+         Context := Associated_Node_For_Itype (Ptr_Typ);
+      else
+         Context := Parent (Ptr_Typ);
+      end if;
+
+      --  Generate:
+      --    <Ptr_Typ>M : Master_Id renames _Master;
+
+      Master_Id :=
+        Make_Defining_Identifier (Loc,
+          New_External_Name (Chars (Ptr_Typ), 'M'));
+
+      Master_Decl :=
+        Make_Object_Renaming_Declaration (Loc,
+          Defining_Identifier => Master_Id,
+          Subtype_Mark        => New_Reference_To (RTE (RE_Master_Id), Loc),
+          Name                => Make_Identifier (Loc, Name_uMaster));
+
+      Insert_Action (Context, Master_Decl);
+
+      --  The renamed master now services the access type
+
+      Set_Master_Id (Ptr_Typ, Master_Id);
+   end Build_Master_Renaming;
+
+   -----------------------------------------
+   -- Build_Private_Protected_Declaration --
+   -----------------------------------------
+
+   function Build_Private_Protected_Declaration
+     (N : Node_Id) return Entity_Id
+   is
+      Loc      : constant Source_Ptr := Sloc (N);
+      Body_Id  : constant Entity_Id := Defining_Entity (N);
+      Decl     : Node_Id;
+      Plist    : List_Id;
+      Formal   : Entity_Id;
+      New_Spec : Node_Id;
+      Spec_Id  : Entity_Id;
+
+   begin
+      Formal := First_Formal (Body_Id);
+
+      --  The protected operation always has at least one formal, namely the
+      --  object itself, but it is only placed in the parameter list if
+      --  expansion is enabled.
+
+      if Present (Formal) or else Expander_Active then
+         Plist := Copy_Parameter_List (Body_Id);
+      else
+         Plist := No_List;
+      end if;
+
+      if Nkind (Specification (N)) = N_Procedure_Specification then
+         New_Spec :=
+           Make_Procedure_Specification (Loc,
+              Defining_Unit_Name       =>
+                Make_Defining_Identifier (Sloc (Body_Id),
+                  Chars => Chars (Body_Id)),
+              Parameter_Specifications =>
+                Plist);
+      else
+         New_Spec :=
+           Make_Function_Specification (Loc,
+             Defining_Unit_Name       =>
+               Make_Defining_Identifier (Sloc (Body_Id),
+                 Chars => Chars (Body_Id)),
+             Parameter_Specifications => Plist,
+             Result_Definition        =>
+               New_Occurrence_Of (Etype (Body_Id), Loc));
+      end if;
 
-         --  If we fall off the top, we are at the outer level, and the
-         --  environment task is our effective master, so nothing to mark.
+      Decl := Make_Subprogram_Declaration (Loc, Specification => New_Spec);
+      Insert_Before (N, Decl);
+      Spec_Id := Defining_Unit_Name (New_Spec);
 
-         if Nkind_In
-              (P, N_Task_Body, N_Block_Statement, N_Subprogram_Body)
-         then
-            Set_Is_Task_Master (P, True);
-            return;
+      --  Indicate that the entity comes from source, to ensure that cross-
+      --  reference information is properly generated. The body itself is
+      --  rewritten during expansion, and the body entity will not appear in
+      --  calls to the operation.
 
-         elsif Nkind (Parent (P)) = N_Subunit then
-            P := Corresponding_Stub (Parent (P));
-         end if;
-      end loop;
-   end Build_Master_Entity;
+      Set_Comes_From_Source (Spec_Id, True);
+      Analyze (Decl);
+      Set_Has_Completion (Spec_Id);
+      Set_Convention (Spec_Id, Convention_Protected);
+      return Spec_Id;
+   end Build_Private_Protected_Declaration;
 
    ---------------------------
    -- Build_Protected_Entry --
@@ -2057,10 +3169,8 @@ package body Exp_Ch9 is
             Make_Attribute_Reference (End_Loc,
               Prefix =>
                 Make_Selected_Component (End_Loc,
-                  Prefix =>
-                    Make_Identifier (End_Loc, Name_uObject),
-                  Selector_Name =>
-                    Make_Identifier (End_Loc, Name_uObject)),
+                  Prefix        => Make_Identifier (End_Loc, Name_uObject),
+                  Selector_Name => Make_Identifier (End_Loc, Name_uObject)),
               Attribute_Name => Name_Unchecked_Access))));
 
       --  When exceptions can not be propagated, we never need to call
@@ -2095,6 +3205,10 @@ package body Exp_Ch9 is
                raise Program_Error;
          end case;
 
+         --  Establish link between subprogram body entity and source entry
+
+         Set_Corresponding_Protected_Entry (Edef, Ent);
+
          --  Create body of entry procedure. The renaming declarations are
          --  placed ahead of the block that contains the actual entry body.
 
@@ -2117,7 +3231,7 @@ package body Exp_Ch9 is
                            Make_Attribute_Reference (Han_Loc,
                              Prefix =>
                                Make_Selected_Component (Han_Loc,
-                                 Prefix =>
+                                 Prefix        =>
                                    Make_Identifier (Han_Loc, Name_uObject),
                                  Selector_Name =>
                                    Make_Identifier (Han_Loc, Name_uObject)),
@@ -2274,6 +3388,11 @@ package body Exp_Ch9 is
 
       Set_Debug_Info_Needed (New_Id);
 
+      --  If a pragma Eliminate applies to the source entity, the internal
+      --  subprograms will be eliminated as well.
+
+      Set_Is_Eliminated (New_Id, Is_Eliminated (Def_Id));
+
       if Nkind (Specification (Decl)) = N_Procedure_Specification then
          New_Spec :=
            Make_Procedure_Specification (Loc,
@@ -2321,6 +3440,7 @@ package body Exp_Ch9 is
       Stmts        : List_Id;
       Object_Parm  : Node_Id;
       Exc_Safe     : Boolean;
+      Lock_Kind    : RE_Id;
 
       function Is_Exception_Safe (Subprogram : Node_Id) return Boolean;
       --  Tell whether a given subprogram cannot raise an exception
@@ -2432,9 +3552,8 @@ package body Exp_Ch9 is
       Uactuals := New_List;
       Pformal := First (Parameter_Specifications (P_Op_Spec));
       while Present (Pformal) loop
-         Append (
-           Make_Identifier (Loc, Chars (Defining_Identifier (Pformal))),
-           Uactuals);
+         Append_To (Uactuals,
+           Make_Identifier (Loc, Chars (Defining_Identifier (Pformal))));
          Next (Pformal);
       end loop;
 
@@ -2443,7 +3562,7 @@ package body Exp_Ch9 is
 
       if Nkind (Op_Spec) = N_Function_Specification then
          if Exc_Safe then
-            R := Make_Defining_Identifier (Loc, New_Internal_Name ('R'));
+            R := Make_Temporary (Loc, 'R');
             Unprot_Call :=
               Make_Object_Declaration (Loc,
                 Defining_Identifier => R,
@@ -2452,27 +3571,32 @@ package body Exp_Ch9 is
                 Expression =>
                   Make_Function_Call (Loc,
                     Name => Make_Identifier (Loc,
-                      Chars (Defining_Unit_Name (N_Op_Spec))),
+                      Chars => Chars (Defining_Unit_Name (N_Op_Spec))),
                     Parameter_Associations => Uactuals));
-            Return_Stmt := Make_Simple_Return_Statement (Loc,
-              Expression => New_Reference_To (R, Loc));
+
+            Return_Stmt :=
+              Make_Simple_Return_Statement (Loc,
+                Expression => New_Reference_To (R, Loc));
 
          else
             Unprot_Call := Make_Simple_Return_Statement (Loc,
               Expression => Make_Function_Call (Loc,
                 Name =>
                   Make_Identifier (Loc,
-                    Chars (Defining_Unit_Name (N_Op_Spec))),
+                    Chars => Chars (Defining_Unit_Name (N_Op_Spec))),
                 Parameter_Associations => Uactuals));
          end if;
 
+         Lock_Kind := RE_Lock_Read_Only;
+
       else
          Unprot_Call :=
            Make_Procedure_Call_Statement (Loc,
              Name =>
-               Make_Identifier (Loc,
-                 Chars (Defining_Unit_Name (N_Op_Spec))),
+               Make_Identifier (Loc, Chars (Defining_Unit_Name (N_Op_Spec))),
              Parameter_Associations => Uactuals);
+
+         Lock_Kind := RE_Lock;
       end if;
 
       --  Wrap call in block that will be covered by an at_end handler
@@ -2497,7 +3621,7 @@ package body Exp_Ch9 is
             Service_Name := New_Reference_To (RTE (RE_Service_Entry), Loc);
 
          when System_Tasking_Protected_Objects =>
-            Lock_Name := New_Reference_To (RTE (RE_Lock), Loc);
+            Lock_Name := New_Reference_To (RTE (Lock_Kind), Loc);
             Service_Name := New_Reference_To (RTE (RE_Unlock), Loc);
 
          when others =>
@@ -2508,10 +3632,8 @@ package body Exp_Ch9 is
         Make_Attribute_Reference (Loc,
            Prefix =>
              Make_Selected_Component (Loc,
-               Prefix =>
-                 Make_Identifier (Loc, Name_uObject),
-             Selector_Name =>
-                 Make_Identifier (Loc, Name_uObject)),
+               Prefix        => Make_Identifier (Loc, Name_uObject),
+               Selector_Name => Make_Identifier (Loc, Name_uObject)),
            Attribute_Name => Name_Unchecked_Access);
 
       Lock_Stmt := Make_Procedure_Call_Statement (Loc,
@@ -2608,6 +3730,18 @@ package body Exp_Ch9 is
          Params := New_List;
       end if;
 
+      --  If the type is an untagged derived type, convert to the root type,
+      --  which is the one on which the operations are defined.
+
+      if Nkind (Rec) = N_Unchecked_Type_Conversion
+        and then not Is_Tagged_Type (Etype (Rec))
+        and then Is_Derived_Type (Etype (Rec))
+      then
+         Set_Etype (Rec, Root_Type (Etype (Rec)));
+         Set_Subtype_Mark (Rec,
+           New_Occurrence_Of (Root_Type (Etype (Rec)), Sloc (N)));
+      end if;
+
       Prepend (Rec, Params);
 
       if Ekind (Sub) = E_Procedure then
@@ -2658,13 +3792,9 @@ package body Exp_Ch9 is
          Name_Len := Name_Len - 1;
       end if;
 
-      Name_Buffer (Name_Len + 1) := '_';
-      Name_Buffer (Name_Len + 2) := '_';
-
-      Name_Len := Name_Len + 2;
+      Add_Str_To_Name_Buffer ("__");
       for J in 1 .. Select_Len loop
-         Name_Len := Name_Len + 1;
-         Name_Buffer (Name_Len) := Select_Buffer (J);
+         Add_Char_To_Name_Buffer (Select_Buffer (J));
       end loop;
 
       --  Now add the Append_Char if specified. The encoding to follow
@@ -2677,13 +3807,10 @@ package body Exp_Ch9 is
 
       if Append_Char /= ' ' then
          if Append_Char = 'P' or Append_Char = 'N' then
-            Name_Len := Name_Len + 1;
-            Name_Buffer (Name_Len) := Append_Char;
+            Add_Char_To_Name_Buffer (Append_Char);
             return Name_Find;
          else
-            Name_Buffer (Name_Len + 1) := '_';
-            Name_Buffer (Name_Len + 2) := Append_Char;
-            Name_Len := Name_Len + 2;
+            Add_Str_To_Name_Buffer ((1 => '_', 2 => Append_Char));
             return New_External_Name (Name_Find, ' ', -1);
          end if;
       else
@@ -2820,11 +3947,11 @@ package body Exp_Ch9 is
 
          if Nkind (Concval) = N_Function_Call
            and then Is_Task_Type (Conctyp)
-           and then Ada_Version >= Ada_05
+           and then Ada_Version >= Ada_2005
          then
             declare
-               Obj : constant Entity_Id :=
-                  Make_Defining_Identifier (Loc, New_Internal_Name ('F'));
+               ExpR : constant Node_Id   := Relocate_Node (Concval);
+               Obj  : constant Entity_Id := Make_Temporary (Loc, 'F', ExpR);
                Decl : Node_Id;
 
             begin
@@ -2832,7 +3959,7 @@ package body Exp_Ch9 is
                  Make_Object_Declaration (Loc,
                    Defining_Identifier => Obj,
                    Object_Definition   => New_Occurrence_Of (Conctyp, Loc),
-                   Expression          => Relocate_Node (Concval));
+                   Expression          => ExpR);
                Set_Etype (Obj, Conctyp);
                Decls := New_List (Decl);
                Rewrite (Concval, New_Occurrence_Of (Obj, Loc));
@@ -2902,11 +4029,9 @@ package body Exp_Ch9 is
                if Is_By_Copy_Type (Etype (Actual)) then
                   N_Node :=
                     Make_Object_Declaration (Loc,
-                      Defining_Identifier =>
-                        Make_Defining_Identifier (Loc,
-                          Chars => New_Internal_Name ('J')),
-                      Aliased_Present => True,
-                      Object_Definition =>
+                      Defining_Identifier => Make_Temporary (Loc, 'J'),
+                      Aliased_Present     => True,
+                      Object_Definition   =>
                         New_Reference_To (Etype (Formal), Loc));
 
                   --  Mark the object as not needing initialization since the
@@ -2940,10 +4065,31 @@ package body Exp_Ch9 is
                       Attribute_Name => Name_Unchecked_Access,
                     Prefix =>
                       New_Reference_To (Defining_Identifier (N_Node), Loc)));
+
+               --  If it is a VM_By_Copy_Actual, copy it to a new variable
+
+               elsif Is_VM_By_Copy_Actual (Actual) then
+                  N_Node :=
+                    Make_Object_Declaration (Loc,
+                      Defining_Identifier => Make_Temporary (Loc, 'J'),
+                      Aliased_Present     => True,
+                      Object_Definition   =>
+                        New_Reference_To (Etype (Formal), Loc),
+                      Expression => New_Copy_Tree (Actual));
+                  Set_Assignment_OK (N_Node);
+
+                  Append (N_Node, Decls);
+
+                  Append_To (Plist,
+                    Make_Attribute_Reference (Loc,
+                      Attribute_Name => Name_Unchecked_Access,
+                    Prefix =>
+                      New_Reference_To (Defining_Identifier (N_Node), Loc)));
+
                else
                   --  Interface class-wide formal
 
-                  if Ada_Version >= Ada_05
+                  if Ada_Version >= Ada_2005
                     and then Ekind (Etype (Formal)) = E_Class_Wide_Type
                     and then Is_Interface (Etype (Formal))
                   then
@@ -3017,13 +4163,12 @@ package body Exp_Ch9 is
 
                   --  Bnn : Communications_Block;
 
-                  Comm_Name :=
-                    Make_Defining_Identifier (Loc, New_Internal_Name ('B'));
+                  Comm_Name := Make_Temporary (Loc, 'B');
 
                   Append_To (Decls,
                     Make_Object_Declaration (Loc,
                       Defining_Identifier => Comm_Name,
-                      Object_Definition =>
+                      Object_Definition   =>
                         New_Reference_To (RTE (RE_Communication_Block), Loc)));
 
                   --  Some additional statements for protected entry calls
@@ -3092,7 +4237,8 @@ package body Exp_Ch9 is
 
             Set_Assignment_OK (Actual);
             while Present (Actual) loop
-               if Is_By_Copy_Type (Etype (Actual))
+               if (Is_By_Copy_Type (Etype (Actual))
+                     or else Is_VM_By_Copy_Actual (Actual))
                  and then Ekind (Formal) /= E_In_Parameter
                then
                   N_Node :=
@@ -3275,23 +4421,20 @@ package body Exp_Ch9 is
       Loc    : constant Source_Ptr := Sloc (N);
       Chain  : constant Entity_Id  :=
                  Make_Defining_Identifier (Loc, Name_uChain);
-
-      Blkent : Entity_Id;
+      Blkent : constant Entity_Id  := Make_Temporary (Loc, 'A');
       Block  : Node_Id;
 
    begin
-      Blkent := Make_Defining_Identifier (Loc, New_Internal_Name ('A'));
-
       Block :=
         Make_Block_Statement (Loc,
-          Identifier => New_Reference_To (Blkent, Loc),
+          Identifier   => New_Reference_To (Blkent, Loc),
           Declarations => New_List (
 
             --  _Chain  : Activation_Chain;
 
             Make_Object_Declaration (Loc,
               Defining_Identifier => Chain,
-              Aliased_Present => True,
+              Aliased_Present     => True,
               Object_Definition   =>
                 New_Reference_To (RTE (RE_Activation_Chain), Loc))),
 
@@ -3340,12 +4483,10 @@ package body Exp_Ch9 is
       Loc    : constant Source_Ptr := Sloc (N);
       Chain  : constant Entity_Id  :=
                  Make_Defining_Identifier (Loc, Name_uChain);
-      Blkent : Entity_Id;
+      Blkent : constant Entity_Id  := Make_Temporary (Loc, 'A');
       Block  : Node_Id;
 
    begin
-      Blkent := Make_Defining_Identifier (Loc, New_Internal_Name ('A'));
-
       Append_To (Init_Stmts,
         Make_Procedure_Call_Statement (Loc,
           Name => New_Reference_To (RTE (RE_Activate_Tasks), Loc),
@@ -3392,9 +4533,21 @@ package body Exp_Ch9 is
       Spec_Id : Entity_Id;
 
    begin
-      Spec_Id :=
-        Make_Defining_Identifier (Loc,
-          Chars => New_External_Name (Chars (T), 'B'));
+      --  Case of explicit task type, suffix TB
+
+      if Comes_From_Source (T) then
+         Spec_Id :=
+           Make_Defining_Identifier (Loc,
+             Chars => New_External_Name (Chars (T), "TB"));
+
+      --  Case of anonymous task type, suffix B
+
+      else
+         Spec_Id :=
+           Make_Defining_Identifier (Loc,
+             Chars => New_External_Name (Chars (T), 'B'));
+      end if;
+
       Set_Is_Internal (Spec_Id);
 
       --  Associate the procedure with the task, if this is the declaration
@@ -3463,9 +4616,7 @@ package body Exp_Ch9 is
       Efam := First_Entity (Conctyp);
       while Present (Efam) loop
          if Ekind (Efam) = E_Entry_Family then
-            Efam_Type :=
-              Make_Defining_Identifier (Loc,
-                Chars => New_Internal_Name ('F'));
+            Efam_Type := Make_Temporary (Loc, 'F');
 
             declare
                Bas : Entity_Id :=
@@ -3480,9 +4631,7 @@ package body Exp_Ch9 is
                  (Discrete_Subtype_Definition (Parent (Efam)), Lo, Hi);
 
                if Is_Potentially_Large_Family (Bas, Conctyp, Lo, Hi) then
-                  Bas :=
-                    Make_Defining_Identifier (Loc,
-                      Chars => New_Internal_Name ('B'));
+                  Bas := Make_Temporary (Loc, 'B');
 
                   Bas_Decl :=
                     Make_Subtype_Declaration (Loc,
@@ -3635,7 +4784,7 @@ package body Exp_Ch9 is
 
    --    objectR
 
-   --  which is a renaming of the _object field of the current object object
+   --  which is a renaming of the _object field of the current object
    --  record, passed into protected operations as a parameter.
 
    function Concurrent_Ref (N : Node_Id) return Node_Id is
@@ -3719,20 +4868,19 @@ package body Exp_Ch9 is
             else
                declare
                   Decl   : Node_Id;
-                  T_Self : constant Entity_Id :=
-                             Make_Defining_Identifier (Loc,
-                               Chars => New_Internal_Name ('T'));
+                  T_Self : constant Entity_Id := Make_Temporary (Loc, 'T');
                   T_Body : constant Node_Id :=
                              Parent (Corresponding_Body (Parent (Entity (N))));
 
                begin
-                  Decl := Make_Object_Declaration (Loc,
-                     Defining_Identifier => T_Self,
-                     Object_Definition =>
-                       New_Occurrence_Of (RTE (RO_ST_Task_Id), Loc),
-                     Expression =>
-                       Make_Function_Call (Loc,
-                         Name => New_Reference_To (RTE (RE_Self), Loc)));
+                  Decl :=
+                    Make_Object_Declaration (Loc,
+                      Defining_Identifier => T_Self,
+                      Object_Definition   =>
+                        New_Occurrence_Of (RTE (RO_ST_Task_Id), Loc),
+                      Expression          =>
+                        Make_Function_Call (Loc,
+                          Name => New_Reference_To (RTE (RE_Self), Loc)));
                   Prepend (Decl, Declarations (T_Body));
                   Analyze (Decl);
                   Set_Scope (T_Self, Entity (N));
@@ -3760,7 +4908,7 @@ package body Exp_Ch9 is
 
          return
            Make_Selected_Component (Loc,
-             Prefix =>
+             Prefix        =>
                Unchecked_Convert_To (Corresponding_Record_Type (Ntyp),
                  New_Copy_Tree (N)),
              Selector_Name => Make_Identifier (Loc, Sel));
@@ -3780,8 +4928,8 @@ package body Exp_Ch9 is
          return N;
       else
          return
-           Unchecked_Convert_To (Corresponding_Record_Type (Typ),
-             New_Copy_Tree (N));
+           Unchecked_Convert_To
+             (Corresponding_Record_Type (Typ), New_Copy_Tree (N));
       end if;
    end Convert_Concurrent;
 
@@ -4007,7 +5155,7 @@ package body Exp_Ch9 is
       Ldecl2 : Node_Id;
 
    begin
-      if Expander_Active then
+      if Full_Expander_Active then
 
          --  If we have no handled statement sequence, we may need to build
          --  a dummy sequence consisting of a null statement. This can be
@@ -4019,7 +5167,7 @@ package body Exp_Ch9 is
          then
             Set_Handled_Statement_Sequence (N,
               Make_Handled_Sequence_Of_Statements (Loc,
-                New_List (Make_Null_Statement (Loc))));
+                Statements => New_List (Make_Null_Statement (Loc))));
          end if;
 
          --  Create and declare two labels to be placed at the end of the
@@ -4029,25 +5177,28 @@ package body Exp_Ch9 is
          --  completes in the middle of the accept body.
 
          if Present (Handled_Statement_Sequence (N)) then
-            Lab_Id := Make_Identifier (Loc, New_Internal_Name ('L'));
-            Set_Entity (Lab_Id,
-              Make_Defining_Identifier (Loc, Chars (Lab_Id)));
-            Lab := Make_Label (Loc, Lab_Id);
-            Ldecl :=
-              Make_Implicit_Label_Declaration (Loc,
-                Defining_Identifier  => Entity (Lab_Id),
-                Label_Construct      => Lab);
-            Append (Lab, Statements (Handled_Statement_Sequence (N)));
-
-            Lab_Id := Make_Identifier (Loc, New_Internal_Name ('L'));
-            Set_Entity (Lab_Id,
-              Make_Defining_Identifier (Loc, Chars (Lab_Id)));
-            Lab := Make_Label (Loc, Lab_Id);
-            Ldecl2 :=
-              Make_Implicit_Label_Declaration (Loc,
-                Defining_Identifier  => Entity (Lab_Id),
-                Label_Construct      => Lab);
-            Append (Lab, Statements (Handled_Statement_Sequence (N)));
+            declare
+               Ent : Entity_Id;
+
+            begin
+               Ent := Make_Temporary (Loc, 'L');
+               Lab_Id := New_Reference_To (Ent, Loc);
+               Lab := Make_Label (Loc, Lab_Id);
+               Ldecl :=
+                 Make_Implicit_Label_Declaration (Loc,
+                   Defining_Identifier  => Ent,
+                   Label_Construct      => Lab);
+               Append (Lab, Statements (Handled_Statement_Sequence (N)));
+
+               Ent := Make_Temporary (Loc, 'L');
+               Lab_Id := New_Reference_To (Ent, Loc);
+               Lab := Make_Label (Loc, Lab_Id);
+               Ldecl2 :=
+                 Make_Implicit_Label_Declaration (Loc,
+                   Defining_Identifier  => Ent,
+                   Label_Construct      => Lab);
+               Append (Lab, Statements (Handled_Statement_Sequence (N)));
+            end;
 
          else
             Ldecl := Empty;
@@ -4059,9 +5210,7 @@ package body Exp_Ch9 is
          if Is_List_Member (N) then
 
             if Present (Handled_Statement_Sequence (N)) then
-               Ann :=
-                 Make_Defining_Identifier (Loc,
-                   Chars => New_Internal_Name ('A'));
+               Ann := Make_Temporary (Loc, 'A');
 
                Adecl :=
                  Make_Object_Declaration (Loc,
@@ -4118,9 +5267,7 @@ package body Exp_Ch9 is
                --  label for requeue expansion must be declared.
 
                if N = Accept_Statement (Alt) then
-                  Ann :=
-                    Make_Defining_Identifier (Loc, New_Internal_Name ('A'));
-
+                  Ann := Make_Temporary (Loc, 'A');
                   Adecl :=
                     Make_Object_Declaration (Loc,
                       Defining_Identifier => Ann,
@@ -4161,10 +5308,11 @@ package body Exp_Ch9 is
            and then Present (Handled_Statement_Sequence (N))
          then
             declare
-               Comp   : Entity_Id;
-               Decl   : Node_Id;
-               Formal : Entity_Id;
-               New_F  : Entity_Id;
+               Comp           : Entity_Id;
+               Decl           : Node_Id;
+               Formal         : Entity_Id;
+               New_F          : Entity_Id;
+               Renamed_Formal : Node_Id;
 
             begin
                Push_Scope (Ent);
@@ -4173,14 +5321,14 @@ package body Exp_Ch9 is
                while Present (Formal) loop
                   Comp  := Entry_Component (Formal);
                   New_F :=
-                    Make_Defining_Identifier (Sloc (Formal), Chars (Formal));
+                    Make_Defining_Identifier (Loc, Chars (Formal));
 
                   Set_Etype (New_F, Etype (Formal));
                   Set_Scope (New_F, Ent);
 
-               --  Now we set debug info needed on New_F even though it does
-               --  not come from source, so that the debugger will get the
-               --  right information for these generated names.
+                  --  Now we set debug info needed on New_F even though it does
+                  --  not come from source, so that the debugger will get the
+                  --  right information for these generated names.
 
                   Set_Debug_Info_Needed (New_F);
 
@@ -4193,21 +5341,18 @@ package body Exp_Ch9 is
 
                   Set_Actual_Subtype (New_F, Actual_Subtype (Formal));
 
+                  Renamed_Formal :=
+                     Make_Selected_Component (Loc,
+                       Prefix        =>
+                         Unchecked_Convert_To (
+                           Entry_Parameters_Type (Ent),
+                           New_Reference_To (Ann, Loc)),
+                       Selector_Name =>
+                         New_Reference_To (Comp, Loc));
+
                   Decl :=
-                    Make_Object_Renaming_Declaration (Loc,
-                      Defining_Identifier =>
-                        New_F,
-                      Subtype_Mark =>
-                        New_Reference_To (Etype (Formal), Loc),
-                      Name =>
-                        Make_Explicit_Dereference (Loc,
-                          Make_Selected_Component (Loc,
-                            Prefix =>
-                              Unchecked_Convert_To (
-                                Entry_Parameters_Type (Ent),
-                                New_Reference_To (Ann, Loc)),
-                            Selector_Name =>
-                              New_Reference_To (Comp, Loc))));
+                    Build_Renamed_Formal_Declaration
+                      (New_F, Formal, Comp, Renamed_Formal);
 
                   if No (Declarations (N)) then
                      Set_Declarations (N, New_List);
@@ -4233,10 +5378,8 @@ package body Exp_Ch9 is
       Comps  : List_Id;
       T      : constant Entity_Id  := Defining_Identifier (N);
       D_T    : constant Entity_Id  := Designated_Type (T);
-      D_T2   : constant Entity_Id  := Make_Defining_Identifier (Loc,
-                                        Chars => New_Internal_Name ('D'));
-      E_T    : constant Entity_Id  := Make_Defining_Identifier (Loc,
-                                        Chars => New_Internal_Name ('E'));
+      D_T2   : constant Entity_Id  := Make_Temporary (Loc, 'D');
+      E_T    : constant Entity_Id  := Make_Temporary (Loc, 'E');
       P_List : constant List_Id    := Build_Protected_Spec
                                         (N, RTE (RE_Address), D_T, False);
       Decl1  : Node_Id;
@@ -4244,9 +5387,9 @@ package body Exp_Ch9 is
       Def1   : Node_Id;
 
    begin
-      --  Create access to protected subprogram with full signature
+      --  Create access to subprogram with full signature
 
-      if Nkind (Type_Definition (N)) = N_Access_Function_Definition then
+      if Etype (D_T) /= Standard_Void_Type then
          Def1 :=
            Make_Access_Function_Definition (Loc,
              Parameter_Specifications => P_List,
@@ -4264,16 +5407,21 @@ package body Exp_Ch9 is
           Defining_Identifier => D_T2,
           Type_Definition => Def1);
 
-      Analyze (Decl1);
       Insert_After (N, Decl1);
+      Analyze (Decl1);
+
+      --  Associate the access to subprogram with its original access to
+      --  protected subprogram type. Needed by the backend to know that this
+      --  type corresponds with an access to protected subprogram type.
+
+      Set_Original_Access_Type (D_T2, T);
 
       --  Create Equivalent_Type, a record with two components for an access to
       --  object and an access to subprogram.
 
       Comps := New_List (
         Make_Component_Declaration (Loc,
-          Defining_Identifier =>
-            Make_Defining_Identifier (Loc, New_Internal_Name ('P')),
+          Defining_Identifier  => Make_Temporary (Loc, 'P'),
           Component_Definition =>
             Make_Component_Definition (Loc,
               Aliased_Present => False,
@@ -4281,24 +5429,22 @@ package body Exp_Ch9 is
                 New_Occurrence_Of (RTE (RE_Address), Loc))),
 
         Make_Component_Declaration (Loc,
-          Defining_Identifier =>
-            Make_Defining_Identifier (Loc, New_Internal_Name ('S')),
+          Defining_Identifier  => Make_Temporary (Loc, 'S'),
           Component_Definition =>
             Make_Component_Definition (Loc,
-              Aliased_Present => False,
+              Aliased_Present    => False,
               Subtype_Indication => New_Occurrence_Of (D_T2, Loc))));
 
       Decl2 :=
         Make_Full_Type_Declaration (Loc,
           Defining_Identifier => E_T,
-          Type_Definition =>
+          Type_Definition     =>
             Make_Record_Definition (Loc,
               Component_List =>
-                Make_Component_List (Loc,
-                  Component_Items => Comps)));
+                Make_Component_List (Loc, Component_Items => Comps)));
 
-      Analyze (Decl2);
       Insert_After (Decl1, Decl2);
+      Analyze (Decl2);
       Set_Equivalent_Type (T, E_T);
    end Expand_Access_Protected_Subprogram_Type;
 
@@ -4330,7 +5476,7 @@ package body Exp_Ch9 is
       --  barrier just as a protected function, and discard the protected
       --  version of it because it is never called.
 
-      if Expander_Active then
+      if Full_Expander_Active then
          B_F := Build_Barrier_Function (N, Ent, Prot);
          Func := Barrier_Function (Ent);
          Set_Corresponding_Spec (B_F, Func);
@@ -4368,7 +5514,7 @@ package body Exp_Ch9 is
          --  condition does not reference any of the generated renamings
          --  within the function.
 
-         if Expander_Active
+         if Full_Expander_Active
            and then Scope (Entity (Cond)) /= Func
          then
             Set_Declarations (B_F, Empty_List);
@@ -4431,7 +5577,7 @@ package body Exp_Ch9 is
          --  A task interface class-wide type object is being aborted.
          --  Retrieve its _task_id by calling a dispatching routine.
 
-         if Ada_Version >= Ada_05
+         if Ada_Version >= Ada_2005
            and then Ekind (Etype (Tasknm)) = E_Class_Wide_Type
            and then Is_Interface (Etype (Tasknm))
            and then Is_Task_Interface (Etype (Tasknm))
@@ -4449,8 +5595,7 @@ package body Exp_Ch9 is
                       New_Reference_To (RTE (RO_ST_Task_Id), Loc),
                     Expression =>
                       Make_Selected_Component (Loc,
-                        Prefix =>
-                          New_Copy_Tree (Tasknm),
+                        Prefix        => New_Copy_Tree (Tasknm),
                         Selector_Name =>
                           Make_Identifier (Loc, Name_uDisp_Get_Task_Id)))));
 
@@ -4613,7 +5758,7 @@ package body Exp_Ch9 is
          --  Construct the block, using the declarations from the accept
          --  statement if any to initialize the declarations of the block.
 
-         Blkent := Make_Defining_Identifier (Loc, New_Internal_Name ('A'));
+         Blkent := Make_Temporary (Loc, 'A');
          Set_Ekind (Blkent, E_Block);
          Set_Etype (Blkent, Standard_Void_Type);
          Set_Scope (Blkent, Current_Scope);
@@ -4624,6 +5769,11 @@ package body Exp_Ch9 is
              Declarations               => Declarations (N),
              Handled_Statement_Sequence => Build_Accept_Body (N));
 
+         --  For the analysis of the generated declarations, the parent node
+         --  must be properly set.
+
+         Set_Parent (Block, Parent (N));
+
          --  Prepend call to Accept_Call to main statement sequence If the
          --  accept has exception handlers, the statement sequence is wrapped
          --  in a block. Insert call and renaming declarations in the
@@ -4974,6 +6124,7 @@ package body Exp_Ch9 is
       Enqueue_Call      : Node_Id;
       Formals           : List_Id;
       Hdle              : List_Id;
+      Handler_Stmt      : Node_Id;
       Index             : Node_Id;
       Lim_Typ_Stmts     : List_Id;
       N_Orig            : Node_Id;
@@ -4985,9 +6136,7 @@ package body Exp_Ch9 is
       ProtP_Stmts       : List_Id;
       Stmt              : Node_Id;
       Stmts             : List_Id;
-      Target_Undefer    : RE_Id;
       TaskE_Stmts       : List_Id;
-      Undefer_Args      : List_Id := No_List;
 
       B   : Entity_Id;  --  Call status flag
       Bnn : Entity_Id;  --  Communication block
@@ -4998,7 +6147,10 @@ package body Exp_Ch9 is
       T   : Entity_Id;  --  Additional status flag
 
    begin
-      Blk_Ent := Make_Defining_Identifier (Loc, New_Internal_Name ('A'));
+      Process_Statements_For_Controlled_Objects (Trig);
+      Process_Statements_For_Controlled_Objects (Abrt);
+
+      Blk_Ent := Make_Temporary (Loc, 'A');
       Ecall   := Triggering_Statement (Trig);
 
       --  The arguments in the call may require dynamic allocation, and the
@@ -5019,7 +6171,7 @@ package body Exp_Ch9 is
       --  trigger which was expanded into a procedure call.
 
       if Nkind (Ecall) = N_Procedure_Call_Statement then
-         if Ada_Version >= Ada_05
+         if Ada_Version >= Ada_2005
            and then
              (No (Original_Node (Ecall))
                 or else not Nkind_In (Original_Node (Ecall),
@@ -5039,13 +6191,11 @@ package body Exp_Ch9 is
             --  Communication block processing, generate:
             --    Bnn : Communication_Block;
 
-            Bnn := Make_Defining_Identifier (Loc, New_Internal_Name ('B'));
-
+            Bnn := Make_Temporary (Loc, 'B');
             Append_To (Decls,
               Make_Object_Declaration (Loc,
-                Defining_Identifier =>
-                  Bnn,
-                Object_Definition =>
+                Defining_Identifier => Bnn,
+                Object_Definition   =>
                   New_Reference_To (RTE (RE_Communication_Block), Loc)));
 
             --  Call kind processing, generate:
@@ -5083,14 +6233,13 @@ package body Exp_Ch9 is
             S := Build_S (Loc, Decls);
 
             --  Additional status flag processing, generate:
+            --    Tnn : Boolean;
 
-            T := Make_Defining_Identifier (Loc, New_Internal_Name ('T'));
-
+            T := Make_Temporary (Loc, 'T');
             Append_To (Decls,
               Make_Object_Declaration (Loc,
-                Defining_Identifier =>
-                  T,
-                Object_Definition =>
+                Defining_Identifier => T,
+                Object_Definition   =>
                   New_Reference_To (Standard_Boolean, Loc)));
 
             ------------------------------
@@ -5115,8 +6264,7 @@ package body Exp_Ch9 is
                   Make_Unchecked_Type_Conversion (Loc,
                     Subtype_Mark =>
                       New_Reference_To (RTE (RE_Communication_Block), Loc),
-                    Expression =>
-                      Make_Identifier (Loc, Name_uD))));
+                    Expression   => Make_Identifier (Loc, Name_uD))));
 
             --  Generate:
             --    _Disp_Asynchronous_Select (<object>, S, P'Address, D, B);
@@ -5175,9 +6323,7 @@ package body Exp_Ch9 is
             --       _clean;
             --    end;
 
-            Cleanup_Block_Ent :=
-              Make_Defining_Identifier (Loc, New_Internal_Name ('C'));
-
+            Cleanup_Block_Ent := Make_Temporary (Loc, 'C');
             Cleanup_Block :=
               Build_Cleanup_Block (Loc, Cleanup_Block_Ent, Cleanup_Stmts, Bnn);
 
@@ -5190,9 +6336,7 @@ package body Exp_Ch9 is
             --       when Abort_Signal => Abort_Undefer;
             --    end;
 
-            Abort_Block_Ent :=
-              Make_Defining_Identifier (Loc, New_Internal_Name ('A'));
-
+            Abort_Block_Ent := Make_Temporary (Loc, 'A');
             ProtE_Stmts :=
               New_List (
                 Make_Implicit_Label_Declaration (Loc,
@@ -5244,8 +6388,7 @@ package body Exp_Ch9 is
                   Make_Unchecked_Type_Conversion (Loc,
                     Subtype_Mark =>
                       New_Reference_To (RTE (RE_Communication_Block), Loc),
-                    Expression =>
-                      Make_Identifier (Loc, Name_uD))));
+                    Expression   => Make_Identifier (Loc, Name_uD))));
 
             --  Generate:
             --    _Disp_Asynchronous_Select (<object>, S, P'Address, D, B);
@@ -5307,9 +6450,7 @@ package body Exp_Ch9 is
             --       _clean;
             --    end;
 
-            Cleanup_Block_Ent :=
-              Make_Defining_Identifier (Loc, New_Internal_Name ('C'));
-
+            Cleanup_Block_Ent := Make_Temporary (Loc, 'C');
             Cleanup_Block :=
               Build_Cleanup_Block (Loc, Cleanup_Block_Ent, Cleanup_Stmts, T);
 
@@ -5322,13 +6463,11 @@ package body Exp_Ch9 is
             --       when Abort_Signal => Abort_Undefer;
             --    end;
 
-            Abort_Block_Ent :=
-              Make_Defining_Identifier (Loc, New_Internal_Name ('A'));
+            Abort_Block_Ent := Make_Temporary (Loc, 'A');
 
             Append_To (TaskE_Stmts,
               Make_Implicit_Label_Declaration (Loc,
-                Defining_Identifier =>
-                  Abort_Block_Ent));
+                Defining_Identifier => Abort_Block_Ent));
 
             Append_To (TaskE_Stmts,
               Build_Abort_Block
@@ -5465,8 +6604,7 @@ package body Exp_Ch9 is
             --  Add a Delay_Block object to the parameter list of the delay
             --  procedure to form the parameter list of the Wait entry call.
 
-            Dblock_Ent :=
-              Make_Defining_Identifier (Loc, New_Internal_Name ('D'));
+            Dblock_Ent := Make_Temporary (Loc, 'D');
 
             Pdef := Entity (Name (Ecall));
 
@@ -5489,13 +6627,7 @@ package body Exp_Ch9 is
 
             --  Create the inner block to protect the abortable part
 
-            Hdle := New_List (
-              Make_Implicit_Exception_Handler (Loc,
-                Exception_Choices =>
-                  New_List (New_Reference_To (Stand.Abort_Signal, Loc)),
-                Statements => New_List (
-                  Make_Procedure_Call_Statement (Loc,
-                    Name => New_Reference_To (RTE (RE_Abort_Undefer), Loc)))));
+            Hdle := New_List (Build_Abort_Block_Handler (Loc));
 
             Prepend_To (Astats,
               Make_Procedure_Call_Statement (Loc,
@@ -5631,8 +6763,7 @@ package body Exp_Ch9 is
          Append_To (Stmts,
            Make_Implicit_If_Statement (N,
              Condition => Make_Function_Call (Loc,
-               Name => New_Reference_To (
-                 RTE (RE_Enqueued), Loc),
+               Name => New_Reference_To (RTE (RE_Enqueued), Loc),
                Parameter_Associations => New_List (
                  New_Reference_To (Cancel_Param, Loc))),
              Then_Statements => Astats));
@@ -5650,13 +6781,25 @@ package body Exp_Ch9 is
          --  See 4jexcept.ads for an explanation.
 
          if VM_Target = No_VM then
-            Target_Undefer := RE_Abort_Undefer;
+            if Exception_Mechanism = Back_End_Exceptions then
+
+               --  Aborts are not deferred at beginning of exception handlers
+               --  in ZCX.
+
+               Handler_Stmt := Make_Null_Statement (Loc);
+
+            else
+               Handler_Stmt := Make_Procedure_Call_Statement (Loc,
+                 Name => New_Reference_To (RTE (RE_Abort_Undefer), Loc),
+                 Parameter_Associations => No_List);
+            end if;
          else
-            Target_Undefer := RE_Update_Exception;
-            Undefer_Args :=
-              New_List (Make_Function_Call (Loc,
-                          Name => New_Occurrence_Of
-                                    (RTE (RE_Current_Target_Exception), Loc)));
+            Handler_Stmt := Make_Procedure_Call_Statement (Loc,
+              Name => New_Reference_To (RTE (RE_Update_Exception), Loc),
+              Parameter_Associations => New_List (
+                Make_Function_Call (Loc,
+                  Name => New_Occurrence_Of
+                            (RTE (RE_Current_Target_Exception), Loc))));
          end if;
 
          Stmts := New_List (
@@ -5679,11 +6822,7 @@ package body Exp_Ch9 is
 
                      Exception_Choices =>
                        New_List (New_Reference_To (Stand.Abort_Signal, Loc)),
-                     Statements => New_List (
-                       Make_Procedure_Call_Statement (Loc,
-                         Name => New_Reference_To (
-                           RTE (Target_Undefer), Loc),
-                         Parameter_Associations => Undefer_Args)))))),
+                     Statements => New_List (Handler_Stmt))))),
 
          --  if not Cancelled (Bnn) then
          --     triggered statements
@@ -5739,14 +6878,7 @@ package body Exp_Ch9 is
 
          --  Create the inner block to protect the abortable part
 
-         Hdle :=  New_List (
-           Make_Implicit_Exception_Handler (Loc,
-             Exception_Choices =>
-               New_List (New_Reference_To (Stand.Abort_Signal, Loc)),
-             Statements =>
-               New_List (
-                 Make_Procedure_Call_Statement (Loc,
-                   Name => New_Reference_To (RTE (RE_Abort_Undefer), Loc)))));
+         Hdle :=  New_List (Build_Abort_Block_Handler (Loc));
 
          Prepend_To (Astats,
            Make_Procedure_Call_Statement (Loc,
@@ -5964,7 +7096,9 @@ package body Exp_Ch9 is
       S : Entity_Id;  --  Primitive operation slot
 
    begin
-      if Ada_Version >= Ada_05
+      Process_Statements_For_Controlled_Objects (N);
+
+      if Ada_Version >= Ada_2005
         and then Nkind (Blk) = N_Procedure_Call_Statement
       then
          Extract_Dispatching_Call (Blk, Call_Ent, Obj, Actuals, Formals);
@@ -6414,8 +7548,7 @@ package body Exp_Ch9 is
 
             --  Declare new access type and then append
 
-            Ctype :=
-              Make_Defining_Identifier (Loc, New_Internal_Name ('A'));
+            Ctype := Make_Temporary (Loc, 'A');
 
             Decl :=
               Make_Full_Type_Declaration (Loc,
@@ -6442,8 +7575,7 @@ package body Exp_Ch9 is
 
          --  Create the Entry_Parameter_Record declaration
 
-         Rec_Ent :=
-           Make_Defining_Identifier (Loc, New_Internal_Name ('P'));
+         Rec_Ent := Make_Temporary (Loc, 'P');
 
          Decl :=
            Make_Full_Type_Declaration (Loc,
@@ -6459,8 +7591,7 @@ package body Exp_Ch9 is
 
          --  Construct and link in the corresponding access type
 
-         Acc_Ent :=
-           Make_Defining_Identifier (Loc, New_Internal_Name ('A'));
+         Acc_Ent := Make_Temporary (Loc, 'A');
 
          Set_Entry_Parameters_Type (Entry_Ent, Acc_Ent);
 
@@ -6473,7 +7604,6 @@ package body Exp_Ch9 is
                  Subtype_Indication => New_Reference_To (Rec_Ent, Loc)));
 
          Insert_After (Last_Decl, Decl);
-         Last_Decl := Decl;
       end if;
    end Expand_N_Entry_Declaration;
 
@@ -6573,13 +7703,13 @@ package body Exp_Ch9 is
    procedure Expand_N_Protected_Body (N : Node_Id) is
       Loc          : constant Source_Ptr := Sloc (N);
       Pid          : constant Entity_Id  := Corresponding_Spec (N);
-      Op_Body      : Node_Id;
-      Op_Decl      : Node_Id;
-      Op_Id        : Entity_Id;
+
+      Current_Node : Node_Id;
       Disp_Op_Body : Node_Id;
       New_Op_Body  : Node_Id;
-      Current_Node : Node_Id;
       Num_Entries  : Natural := 0;
+      Op_Body      : Node_Id;
+      Op_Id        : Entity_Id;
 
       function Build_Dispatching_Subprogram_Body
         (N        : Node_Id;
@@ -6621,11 +7751,10 @@ package body Exp_Ch9 is
          --  Generate a specification without a letter suffix in order to
          --  override an interface function or procedure.
 
-         Spec :=
-           Build_Protected_Sub_Specification (N, Pid, Dispatching_Mode);
+         Spec := Build_Protected_Sub_Specification (N, Pid, Dispatching_Mode);
 
-         --  The formal parameters become the actuals of the protected
-         --  function or procedure call.
+         --  The formal parameters become the actuals of the protected function
+         --  or procedure call.
 
          Actuals := New_List;
          Formal  := First (Parameter_Specifications (Spec));
@@ -6658,8 +7787,8 @@ package body Exp_Ch9 is
 
          return
            Make_Subprogram_Body (Loc,
-             Declarations  => Empty_List,
-             Specification => Spec,
+             Declarations               => Empty_List,
+             Specification              => Spec,
              Handled_Statement_Sequence =>
                Make_Handled_Sequence_Of_Statements (Loc, Stmts));
       end Build_Dispatching_Subprogram_Body;
@@ -6672,14 +7801,12 @@ package body Exp_Ch9 is
          return;
       end if;
 
-      if Nkind (Parent (N)) = N_Subunit then
-
-         --  This is the proper body corresponding to a stub. The declarations
-         --  must be inserted at the point of the stub, which is in the decla-
-         --  rative part of the parent unit.
+      --  This is the proper body corresponding to a stub. The declarations
+      --  must be inserted at the point of the stub, which in turn is in the
+      --  declarative part of the parent unit.
 
+      if Nkind (Parent (N)) = N_Subunit then
          Current_Node := Corresponding_Stub (Parent (N));
-
       else
          Current_Node := N;
       end if;
@@ -6700,7 +7827,7 @@ package body Exp_Ch9 is
 
             when N_Subprogram_Body =>
 
-               --  Exclude functions created to analyze defaults
+               --  Do not create bodies for eliminated operations
 
                if not Is_Eliminated (Defining_Entity (Op_Body))
                  and then not Is_Eliminated (Corresponding_Spec (Op_Body))
@@ -6708,25 +7835,6 @@ package body Exp_Ch9 is
                   New_Op_Body :=
                     Build_Unprotected_Subprogram_Body (Op_Body, Pid);
 
-                  --  Propagate the finalization chain to the new body.
-                  --  In the unlikely event that the subprogram contains a
-                  --  declaration or allocator for an object that requires
-                  --  finalization, the corresponding chain is created when
-                  --  analyzing the body, and attached to its entity. This
-                  --  entity is not further elaborated, and so the chain
-                  --  properly belongs to the newly created subprogram body.
-
-                  if Present
-                    (Finalization_Chain_Entity (Defining_Entity (Op_Body)))
-                  then
-                     Set_Finalization_Chain_Entity
-                       (Protected_Body_Subprogram
-                         (Corresponding_Spec (Op_Body)),
-                       Finalization_Chain_Entity (Defining_Entity (Op_Body)));
-                     Set_Analyzed
-                         (Handled_Statement_Sequence (New_Op_Body), False);
-                  end if;
-
                   Insert_After (Current_Node, New_Op_Body);
                   Current_Node := New_Op_Body;
                   Analyze (New_Op_Body);
@@ -6735,45 +7843,40 @@ package body Exp_Ch9 is
                   --  appear that this is needed only if this is a visible
                   --  operation of the type, or if it is an interrupt handler,
                   --  and this was the strategy used previously in GNAT.
-                  --  However, the operation may be exported through a
-                  --  'Access to an external caller. This is the common idiom
-                  --  in code that uses the Ada 2005 Timing_Events package
-                  --  As a result we need to produce the protected body for
-                  --  both visible and private operations.
+                  --  However, the operation may be exported through a 'Access
+                  --  to an external caller. This is the common idiom in code
+                  --  that uses the Ada 2005 Timing_Events package. As a result
+                  --  we need to produce the protected body for both visible
+                  --  and private operations, as well as operations that only
+                  --  have a body in the source, and for which we create a
+                  --  declaration in the protected body itself.
 
                   if Present (Corresponding_Spec (Op_Body)) then
-                     Op_Decl :=
-                       Unit_Declaration_Node (Corresponding_Spec (Op_Body));
-
-                     if Nkind (Parent (Op_Decl)) =
-                          N_Protected_Definition
-                     then
-                        New_Op_Body :=
-                          Build_Protected_Subprogram_Body (
-                            Op_Body, Pid, Specification (New_Op_Body));
+                     New_Op_Body :=
+                       Build_Protected_Subprogram_Body (
+                         Op_Body, Pid, Specification (New_Op_Body));
 
-                        Insert_After (Current_Node, New_Op_Body);
-                        Analyze (New_Op_Body);
+                     Insert_After (Current_Node, New_Op_Body);
+                     Analyze (New_Op_Body);
 
-                        Current_Node := New_Op_Body;
+                     Current_Node := New_Op_Body;
 
-                        --  Generate an overriding primitive operation body for
-                        --  this subprogram if the protected type implements
-                        --  an interface.
+                     --  Generate an overriding primitive operation body for
+                     --  this subprogram if the protected type implements an
+                     --  interface.
 
-                        if Ada_Version >= Ada_05
-                          and then Present (Abstract_Interfaces (
-                                     Corresponding_Record_Type (Pid)))
-                        then
-                           Disp_Op_Body :=
-                             Build_Dispatching_Subprogram_Body (
-                               Op_Body, Pid, New_Op_Body);
+                     if Ada_Version >= Ada_2005
+                          and then
+                        Present (Interfaces (Corresponding_Record_Type (Pid)))
+                     then
+                        Disp_Op_Body :=
+                          Build_Dispatching_Subprogram_Body
+                            (Op_Body, Pid, New_Op_Body);
 
-                           Insert_After (Current_Node, Disp_Op_Body);
-                           Analyze (Disp_Op_Body);
+                        Insert_After (Current_Node, Disp_Op_Body);
+                        Analyze (Disp_Op_Body);
 
-                           Current_Node := Disp_Op_Body;
-                        end if;
+                        Current_Node := Disp_Op_Body;
                      end if;
                   end if;
                end if;
@@ -6829,8 +7932,8 @@ package body Exp_Ch9 is
       end loop;
 
       --  Finally, create the body of the function that maps an entry index
-      --  into the corresponding body index, except when there is no entry,
-      --  or in a ravenscar-like profile.
+      --  into the corresponding body index, except when there is no entry, or
+      --  in a Ravenscar-like profile.
 
       if Corresponding_Runtime_Package (Pid) =
            System_Tasking_Protected_Objects_Entries
@@ -6841,64 +7944,12 @@ package body Exp_Ch9 is
          Analyze (New_Op_Body);
       end if;
 
-      --  Ada 2005 (AI-345): Construct the primitive entry wrapper bodies after
-      --  the protected body. At this point the entry specs have been created,
+      --  Ada 2005 (AI-345): Construct the primitive wrapper bodies after the
+      --  protected body. At this point all wrapper specs have been created,
       --  frozen and included in the dispatch table for the protected type.
 
-      pragma Assert (Present (Corresponding_Record_Type (Pid)));
-
-      if Ada_Version >= Ada_05
-        and then Present (Protected_Definition (Parent (Pid)))
-        and then Present (Abstract_Interfaces
-                           (Corresponding_Record_Type (Pid)))
-      then
-         declare
-            Vis_Decl  : Node_Id :=
-                          First (Visible_Declarations
-                                  (Protected_Definition (Parent (Pid))));
-            Wrap_Body : Node_Id;
-
-         begin
-            --  Examine the visible declarations of the protected type, looking
-            --  for an entry declaration. We do not consider entry families
-            --  since they cannot have dispatching operations, thus they do not
-            --  need entry wrappers.
-
-            while Present (Vis_Decl) loop
-               if Nkind (Vis_Decl) = N_Entry_Declaration then
-                  Wrap_Body :=
-                    Build_Wrapper_Body (Loc,
-                      Proc_Nam => Defining_Identifier (Vis_Decl),
-                      Obj_Typ  => Corresponding_Record_Type (Pid),
-                      Formals  => Parameter_Specifications (Vis_Decl));
-
-                  if Wrap_Body /= Empty then
-                     Insert_After (Current_Node, Wrap_Body);
-                     Current_Node := Wrap_Body;
-
-                     Analyze (Wrap_Body);
-                  end if;
-
-               elsif Nkind (Vis_Decl) = N_Subprogram_Declaration then
-                  Wrap_Body :=
-                    Build_Wrapper_Body (Loc,
-                      Proc_Nam => Defining_Unit_Name
-                                        (Specification (Vis_Decl)),
-                      Obj_Typ  => Corresponding_Record_Type (Pid),
-                      Formals  => Parameter_Specifications
-                                        (Specification (Vis_Decl)));
-
-                  if Wrap_Body /= Empty then
-                     Insert_After (Current_Node, Wrap_Body);
-                     Current_Node := Wrap_Body;
-
-                     Analyze (Wrap_Body);
-                  end if;
-               end if;
-
-               Next (Vis_Decl);
-            end loop;
-         end;
+      if Ada_Version >= Ada_2005 then
+         Build_Wrapper_Bodies (Loc, Pid, Current_Node);
       end if;
    end Expand_N_Protected_Body;
 
@@ -6982,7 +8033,7 @@ package body Exp_Ch9 is
       Loc      : constant Source_Ptr := Sloc (N);
       Prot_Typ : constant Entity_Id  := Defining_Identifier (N);
 
-      Pdef     : constant Node_Id    := Protected_Definition (N);
+      Pdef : constant Node_Id := Protected_Definition (N);
       --  This contains two lists; one for visible and one for private decls
 
       Rec_Decl     : Node_Id;
@@ -7002,10 +8053,68 @@ package body Exp_Ch9 is
       E_Count      : Int;
       Object_Comp  : Node_Id;
 
+      procedure Check_Inlining (Subp : Entity_Id);
+      --  If the original operation has a pragma Inline, propagate the flag
+      --  to the internal body, for possible inlining later on. The source
+      --  operation is invisible to the back-end and is never actually called.
+
+      function Static_Component_Size (Comp : Entity_Id) return Boolean;
+      --  When compiling under the Ravenscar profile, private components must
+      --  have a static size, or else a protected object  will require heap
+      --  allocation, violating the corresponding restriction. It is preferable
+      --  to make this check here, because it provides a better error message
+      --  than the back-end, which refers to the object as a whole.
+
       procedure Register_Handler;
       --  For a protected operation that is an interrupt handler, add the
       --  freeze action that will register it as such.
 
+      --------------------
+      -- Check_Inlining --
+      --------------------
+
+      procedure Check_Inlining (Subp : Entity_Id) is
+      begin
+         if Is_Inlined (Subp) then
+            Set_Is_Inlined (Protected_Body_Subprogram (Subp));
+            Set_Is_Inlined (Subp, False);
+         end if;
+      end Check_Inlining;
+
+      ---------------------------------
+      -- Check_Static_Component_Size --
+      ---------------------------------
+
+      function Static_Component_Size (Comp : Entity_Id) return Boolean is
+         Typ : constant Entity_Id := Etype (Comp);
+         C   : Entity_Id;
+
+      begin
+         if Is_Scalar_Type (Typ) then
+            return True;
+
+         elsif Is_Array_Type (Typ) then
+            return Compile_Time_Known_Bounds (Typ);
+
+         elsif Is_Record_Type (Typ) then
+            C := First_Component (Typ);
+            while Present (C) loop
+               if not Static_Component_Size (C) then
+                  return False;
+               end if;
+
+               Next_Component (C);
+            end loop;
+
+            return True;
+
+         --  Any other types will be checked by the back-end
+
+         else
+            return True;
+         end if;
+      end Static_Component_Size;
+
       ----------------------
       -- Register_Handler --
       ----------------------
@@ -7045,11 +8154,6 @@ package body Exp_Ch9 is
 
       Cdecls := Component_Items (Component_List (Type_Definition (Rec_Decl)));
 
-      --  Ada 2005 (AI-345): Propagate the attribute that contains the list
-      --  of implemented interfaces.
-
-      Set_Interface_List (Type_Definition (Rec_Decl), Interface_List (N));
-
       Qualify_Entity_Names (N);
 
       --  If the type has discriminants, their occurrences in the declaration
@@ -7137,7 +8241,9 @@ package body Exp_Ch9 is
                           Make_Integer_Literal (Loc, Num_Attach_Handler))));
             end if;
 
-         elsif Has_Interrupt_Handler (Prot_Typ) then
+         elsif Has_Interrupt_Handler (Prot_Typ)
+           and then not Restriction_Active (No_Dynamic_Attachment)
+         then
             Protection_Subtype :=
                Make_Subtype_Indication (
                  Sloc => Loc,
@@ -7151,7 +8257,7 @@ package body Exp_Ch9 is
          --  Type has explicit entries or generated primitive entry wrappers
 
          elsif Has_Entries (Prot_Typ)
-           or else (Ada_Version >= Ada_05
+           or else (Ada_Version >= Ada_2005
                       and then Present (Interface_List (N)))
          then
             case Corresponding_Runtime_Package (Prot_Typ) is
@@ -7197,6 +8303,24 @@ package body Exp_Ch9 is
          while Present (Priv) loop
 
             if Nkind (Priv) = N_Component_Declaration then
+               if not Static_Component_Size (Defining_Identifier (Priv)) then
+
+                  --  When compiling for a restricted profile, the private
+                  --  components must have a static size. If not, this is an
+                  --  error for a single protected declaration, and rates a
+                  --  warning on a protected type declaration.
+
+                  if not Comes_From_Source (Prot_Typ) then
+                     Check_Restriction (No_Implicit_Heap_Allocations, Priv);
+
+                  elsif Restriction_Active (No_Implicit_Heap_Allocations) then
+                     Error_Msg_N ("component has non-static size?", Priv);
+                     Error_Msg_NE
+                       ("\creation of protected object of type& will violate"
+                        & " restriction No_Implicit_Heap_Allocations?",
+                        Priv, Prot_Typ);
+                  end if;
+               end if;
 
                --  The component definition consists of a subtype indication,
                --  or (in Ada 2005) an access definition. Make a copy of the
@@ -7204,20 +8328,23 @@ package body Exp_Ch9 is
 
                declare
                   Old_Comp : constant Node_Id   := Component_Definition (Priv);
-                  Pent     : constant Entity_Id := Defining_Identifier (Priv);
+                  Oent     : constant Entity_Id := Defining_Identifier (Priv);
                   New_Comp : Node_Id;
+                  Nent     : constant Entity_Id :=
+                               Make_Defining_Identifier (Sloc (Oent),
+                                 Chars => Chars (Oent));
 
                begin
                   if Present (Subtype_Indication (Old_Comp)) then
                      New_Comp :=
-                       Make_Component_Definition (Sloc (Pent),
+                       Make_Component_Definition (Sloc (Oent),
                          Aliased_Present    => False,
                          Subtype_Indication =>
                            New_Copy_Tree (Subtype_Indication (Old_Comp),
                                            Discr_Map));
                   else
                      New_Comp :=
-                       Make_Component_Definition (Sloc (Pent),
+                       Make_Component_Definition (Sloc (Oent),
                          Aliased_Present    => False,
                          Access_Definition  =>
                            New_Copy_Tree (Access_Definition (Old_Comp),
@@ -7226,10 +8353,12 @@ package body Exp_Ch9 is
 
                   New_Priv :=
                     Make_Component_Declaration (Loc,
-                      Defining_Identifier =>
-                        Make_Defining_Identifier (Sloc (Pent), Chars (Pent)),
+                      Defining_Identifier  => Nent,
                       Component_Definition => New_Comp,
-                      Expression => Expression (Priv));
+                      Expression           => Expression (Priv));
+
+                  Set_Has_Per_Object_Constraint (Nent,
+                    Has_Per_Object_Constraint (Oent));
 
                   Append_To (Cdecls, New_Priv);
                end;
@@ -7254,7 +8383,7 @@ package body Exp_Ch9 is
                Set_Protected_Body_Subprogram
                  (Defining_Unit_Name (Specification (Priv)),
                   Defining_Unit_Name (Specification (Sub)));
-
+               Check_Inlining (Defining_Unit_Name (Specification (Priv)));
                Current_Node := Sub;
 
                Sub :=
@@ -7296,67 +8425,11 @@ package body Exp_Ch9 is
       Analyze (Rec_Decl, Suppress => All_Checks);
 
       --  Ada 2005 (AI-345): Construct the primitive entry wrappers before
-      --  the corresponding record is frozen
-
-      if Ada_Version >= Ada_05
-        and then Present (Visible_Declarations (Pdef))
-        and then Present (Corresponding_Record_Type
-                          (Defining_Identifier (Parent (Pdef))))
-        and then Present (Abstract_Interfaces
-                          (Corresponding_Record_Type
-                           (Defining_Identifier (Parent (Pdef)))))
-      then
-         declare
-            Current_Node : Node_Id := Rec_Decl;
-            Vis_Decl     : Node_Id;
-            Wrap_Spec    : Node_Id;
-            New_N        : Node_Id;
-
-         begin
-            --  Examine the visible declarations of the protected type, looking
-            --  for declarations of entries, and subprograms. We do not
-            --  consider entry families since they cannot have dispatching
-            --  operations, thus they do not need entry wrappers.
-
-            Vis_Decl := First (Visible_Declarations (Pdef));
-
-            while Present (Vis_Decl) loop
-
-               Wrap_Spec := Empty;
-
-               if Nkind (Vis_Decl) = N_Entry_Declaration
-                 and then No (Discrete_Subtype_Definition (Vis_Decl))
-               then
-                  Wrap_Spec :=
-                    Build_Wrapper_Spec (Loc,
-                      Proc_Nam => Defining_Identifier (Vis_Decl),
-                      Obj_Typ  => Defining_Identifier (Rec_Decl),
-                      Formals  => Parameter_Specifications (Vis_Decl));
-
-               elsif Nkind (Vis_Decl) = N_Subprogram_Declaration then
-                  Wrap_Spec :=
-                    Build_Wrapper_Spec (Loc,
-                      Proc_Nam => Defining_Unit_Name
-                                    (Specification (Vis_Decl)),
-                      Obj_Typ  => Defining_Identifier (Rec_Decl),
-                      Formals  => Parameter_Specifications
-                                    (Specification (Vis_Decl)));
-
-               end if;
+      --  the corresponding record is frozen. If any wrappers are generated,
+      --  Current_Node is updated accordingly.
 
-               if Wrap_Spec /= Empty then
-                  New_N := Make_Subprogram_Declaration (Loc,
-                             Specification => Wrap_Spec);
-
-                  Insert_After (Current_Node, New_N);
-                  Current_Node := New_N;
-
-                  Analyze (New_N);
-               end if;
-
-               Next (Vis_Decl);
-            end loop;
-         end;
+      if Ada_Version >= Ada_2005 then
+         Build_Wrapper_Specs (Loc, Prot_Typ, Current_Node);
       end if;
 
       --  Collect pointers to entry bodies and their barriers, to be placed
@@ -7365,9 +8438,7 @@ package body Exp_Ch9 is
       --  this array. The array is declared after all protected subprograms.
 
       if Has_Entries (Prot_Typ) then
-         Entries_Aggr :=
-           Make_Aggregate (Loc, Expressions => New_List);
-
+         Entries_Aggr := Make_Aggregate (Loc, Expressions => New_List);
       else
          Entries_Aggr := Empty;
       end if;
@@ -7384,9 +8455,7 @@ package body Exp_Ch9 is
       Comp := First (Visible_Declarations (Pdef));
 
       while Present (Comp) loop
-         if Nkind (Comp) = N_Subprogram_Declaration
-           and then not Is_Eliminated (Defining_Entity (Comp))
-         then
+         if Nkind (Comp) = N_Subprogram_Declaration then
             Sub :=
               Make_Subprogram_Declaration (Loc,
                 Specification =>
@@ -7399,6 +8468,7 @@ package body Exp_Ch9 is
             Set_Protected_Body_Subprogram
               (Defining_Unit_Name (Specification (Comp)),
                Defining_Unit_Name (Specification (Sub)));
+            Check_Inlining (Defining_Unit_Name (Specification (Comp)));
 
             --  Make the protected version of the subprogram available for
             --  expansion of external calls.
@@ -7419,10 +8489,9 @@ package body Exp_Ch9 is
             --  Generate an overriding primitive operation specification for
             --  this subprogram if the protected type implements an interface.
 
-            if Ada_Version >= Ada_05
+            if Ada_Version >= Ada_2005
               and then
-                Present (Abstract_Interfaces
-                          (Corresponding_Record_Type (Prot_Typ)))
+                Present (Interfaces (Corresponding_Record_Type (Prot_Typ)))
             then
                Sub :=
                  Make_Subprogram_Declaration (Loc,
@@ -7465,6 +8534,10 @@ package body Exp_Ch9 is
             Insert_After (Current_Node, Sub);
             Analyze (Sub);
 
+            --  Build wrapper procedure for pre/postconditions
+
+            Build_PPC_Wrapper (Comp_Id, N);
+
             Set_Protected_Body_Subprogram
               (Defining_Identifier (Comp),
                Defining_Unit_Name (Specification (Sub)));
@@ -7725,8 +8798,10 @@ package body Exp_Ch9 is
    --     when all others =>
    --        Exceptional_Complete_Rendezvous (Get_GNAT_Exception);
 
-   --  Ada 2005 (AI05-0030): Dispatching requeue from protected to interface
-   --  class-wide type:
+   --  Ada 2012 (AI05-0030): Dispatching requeue to an interface primitive
+   --  marked by pragma Implemented (XXX, By_Entry).
+
+   --  The requeue is inside a protected entry:
 
    --  procedure entE
    --    (O : System.Address;
@@ -7762,10 +8837,9 @@ package body Exp_Ch9 is
    --     end;
    --  end entE;
 
-   --  Ada 2005 (AI05-0030): Dispatching requeue from task to interface
-   --  class-wide type:
+   --  The requeue is inside a task entry:
 
-   --  Accept_Call (E, Ann);
+   --    Accept_Call (E, Ann);
    --     <start of statement sequence for accept statement>
    --     _Disp_Requeue
    --       (<interface class-wide object>,
@@ -7781,225 +8855,576 @@ package body Exp_Ch9 is
    --     <<Lnn>>
    --     Complete_Rendezvous;
 
-   --  exception
-   --     when all others =>
-   --        Exceptional_Complete_Rendezvous (Get_GNAT_Exception);
+   --  exception
+   --     when all others =>
+   --        Exceptional_Complete_Rendezvous (Get_GNAT_Exception);
+
+   --  Ada 2012 (AI05-0030): Dispatching requeue to an interface primitive
+   --  marked by pragma Implemented (XXX, By_Protected_Procedure). The requeue
+   --  statement is replaced by a dispatching call with actual parameters taken
+   --  from the inner-most accept statement or entry body.
+
+   --    Target.Primitive (Param1, ..., ParamN);
+
+   --  Ada 2012 (AI05-0030): Dispatching requeue to an interface primitive
+   --  marked by pragma Implemented (XXX, By_Any) or not marked at all.
+
+   --    declare
+   --       S : constant Offset_Index :=
+   --             Get_Offset_Index (Tag (Concval), DT_Position (Ename));
+   --       C : constant Prim_Op_Kind := Get_Prim_Op_Kind (Tag (Concval), S);
+
+   --    begin
+   --       if C = POK_Protected_Entry
+   --         or else C = POK_Task_Entry
+   --       then
+   --          <statements for dispatching requeue>
+
+   --       elsif C = POK_Protected_Procedure then
+   --          <dispatching call equivalent>
+
+   --       else
+   --          raise Program_Error;
+   --       end if;
+   --    end;
+
+   procedure Expand_N_Requeue_Statement (N : Node_Id) is
+      Loc      : constant Source_Ptr := Sloc (N);
+      Conc_Typ : Entity_Id;
+      Concval  : Node_Id;
+      Ename    : Node_Id;
+      Index    : Node_Id;
+      Old_Typ  : Entity_Id;
+
+      function Build_Dispatching_Call_Equivalent return Node_Id;
+      --  Ada 2012 (AI05-0030): N denotes a dispatching requeue statement of
+      --  the form Concval.Ename. It is statically known that Ename is allowed
+      --  to be implemented by a protected procedure. Create a dispatching call
+      --  equivalent of Concval.Ename taking the actual parameters from the
+      --  inner-most accept statement or entry body.
+
+      function Build_Dispatching_Requeue return Node_Id;
+      --  Ada 2012 (AI05-0030): N denotes a dispatching requeue statement of
+      --  the form Concval.Ename. It is statically known that Ename is allowed
+      --  to be implemented by a protected or a task entry. Create a call to
+      --  primitive _Disp_Requeue which handles the low-level actions.
+
+      function Build_Dispatching_Requeue_To_Any return Node_Id;
+      --  Ada 2012 (AI05-0030): N denotes a dispatching requeue statement of
+      --  the form Concval.Ename. Ename is either marked by pragma Implemented
+      --  (XXX, By_Any) or not marked at all. Create a block which determines
+      --  at runtime whether Ename denotes an entry or a procedure and perform
+      --  the appropriate kind of dispatching select.
+
+      function Build_Normal_Requeue return Node_Id;
+      --  N denotes a non-dispatching requeue statement to either a task or a
+      --  protected entry. Build the appropriate runtime call to perform the
+      --  action.
+
+      function Build_Skip_Statement (Search : Node_Id) return Node_Id;
+      --  For a protected entry, create a return statement to skip the rest of
+      --  the entry body. Otherwise, create a goto statement to skip the rest
+      --  of a task accept statement. The lookup for the enclosing entry body
+      --  or accept statement starts from Search.
+
+      ---------------------------------------
+      -- Build_Dispatching_Call_Equivalent --
+      ---------------------------------------
+
+      function Build_Dispatching_Call_Equivalent return Node_Id is
+         Call_Ent : constant Entity_Id := Entity (Ename);
+         Obj      : constant Node_Id   := Original_Node (Concval);
+         Acc_Ent  : Node_Id;
+         Actuals  : List_Id;
+         Formal   : Node_Id;
+         Formals  : List_Id;
+
+      begin
+         --  Climb the parent chain looking for the inner-most entry body or
+         --  accept statement.
+
+         Acc_Ent := N;
+         while Present (Acc_Ent)
+           and then not Nkind_In (Acc_Ent, N_Accept_Statement,
+                                           N_Entry_Body)
+         loop
+            Acc_Ent := Parent (Acc_Ent);
+         end loop;
+
+         --  A requeue statement should be housed inside an entry body or an
+         --  accept statement at some level. If this is not the case, then the
+         --  tree is malformed.
+
+         pragma Assert (Present (Acc_Ent));
+
+         --  Recover the list of formal parameters
+
+         if Nkind (Acc_Ent) = N_Entry_Body then
+            Acc_Ent := Entry_Body_Formal_Part (Acc_Ent);
+         end if;
+
+         Formals := Parameter_Specifications (Acc_Ent);
+
+         --  Create the actual parameters for the dispatching call. These are
+         --  simply copies of the entry body or accept statement formals in the
+         --  same order as they appear.
+
+         Actuals := No_List;
+
+         if Present (Formals) then
+            Actuals := New_List;
+            Formal  := First (Formals);
+            while Present (Formal) loop
+               Append_To (Actuals,
+                 Make_Identifier (Loc, Chars (Defining_Identifier (Formal))));
+               Next (Formal);
+            end loop;
+         end if;
+
+         --  Generate:
+         --    Obj.Call_Ent (Actuals);
+
+         return
+           Make_Procedure_Call_Statement (Loc,
+             Name =>
+               Make_Selected_Component (Loc,
+                 Prefix        => Make_Identifier (Loc, Chars (Obj)),
+                 Selector_Name => Make_Identifier (Loc, Chars (Call_Ent))),
+
+             Parameter_Associations => Actuals);
+      end Build_Dispatching_Call_Equivalent;
+
+      -------------------------------
+      -- Build_Dispatching_Requeue --
+      -------------------------------
+
+      function Build_Dispatching_Requeue return Node_Id is
+         Params : constant List_Id := New_List;
+
+      begin
+         --  Process the "with abort" parameter
 
-   --  Further details on these expansions can be found in Expand_N_Protected_
-   --  Body and Expand_N_Accept_Statement.
+         Prepend_To (Params,
+           New_Reference_To (Boolean_Literals (Abort_Present (N)), Loc));
 
-   procedure Expand_N_Requeue_Statement (N : Node_Id) is
-      Loc        : constant Source_Ptr := Sloc (N);
-      Abortable  : Node_Id;
-      Acc_Stat   : Node_Id;
-      Conc_Typ   : Entity_Id;
-      Concval    : Node_Id;
-      Ename      : Node_Id;
-      Index      : Node_Id;
-      Lab_Node   : Node_Id;
-      New_Param  : Node_Id;
-      Old_Typ    : Entity_Id;
-      Params     : List_Id;
-      Rcall      : Node_Id;
-      RTS_Call   : Entity_Id;
-      Self_Param : Node_Id;
-      Skip_Stat  : Node_Id;
+         --  Process the entry wrapper's position in the primary dispatch
+         --  table parameter. Generate:
 
-   begin
-      Abortable :=
-        New_Occurrence_Of (Boolean_Literals (Abort_Present (N)), Loc);
+         --    Ada.Tags.Get_Offset_Index
+         --      (Ada.Tags.Tag (Concval),
+         --       <interface dispatch table position of Ename>)
 
-      --  Extract the components of the entry call
+         if Tagged_Type_Expansion then
+            Prepend_To (Params,
+              Make_Function_Call (Loc,
+                Name => New_Reference_To (RTE (RE_Get_Offset_Index), Loc),
+                Parameter_Associations => New_List (
+                  Unchecked_Convert_To (RTE (RE_Tag), Concval),
+                  Make_Integer_Literal (Loc, DT_Position (Entity (Ename))))));
 
-      Extract_Entry (N, Concval, Ename, Index);
-      Conc_Typ := Etype (Concval);
+         --  VM targets
 
-      --  Examine the scope stack in order to find nearest enclosing protected
-      --  or task type. This will constitute our invocation source.
+         else
+            Prepend_To (Params,
+              Make_Function_Call (Loc,
+                Name => New_Reference_To (RTE (RE_Get_Offset_Index), Loc),
 
-      Old_Typ := Current_Scope;
-      while Present (Old_Typ)
-        and then not Is_Protected_Type (Old_Typ)
-        and then not Is_Task_Type (Old_Typ)
-      loop
-         Old_Typ := Scope (Old_Typ);
-      end loop;
+                Parameter_Associations => New_List (
 
-      --  Generate the parameter list for all cases. The abortable flag is
-      --  common among dispatching and regular requeue.
+                  --  Obj_Typ
 
-      Params := New_List (Abortable);
+                  Make_Attribute_Reference (Loc,
+                    Prefix         => Concval,
+                    Attribute_Name => Name_Tag),
 
-      --  Ada 2005 (AI05-0030): We have a dispatching requeue of the form
-      --  Concval.Ename where the type of Concval is class-wide concurrent
-      --  interface.
+                  --  Tag_Typ
 
-      if Ada_Version >= Ada_05
-        and then Present (Concval)
-        and then Is_Class_Wide_Type (Conc_Typ)
-        and then Is_Concurrent_Interface (Conc_Typ)
-      then
-         RTS_Call := Make_Identifier (Loc, Name_uDisp_Requeue);
+                  Make_Attribute_Reference (Loc,
+                    Prefix         => New_Reference_To (Etype (Concval), Loc),
+                    Attribute_Name => Name_Tag),
 
-         --  Generate:
-         --    Ada.Tags.Get_Offset_Index
-         --      (Ada.Tags.Tag (Concval),
-         --       <interface dispatch table position of Ename>)
+                  --  Position
 
-         Prepend_To (Params,
-           Make_Function_Call (Loc,
-             Name =>
-               New_Reference_To (RTE (RE_Get_Offset_Index), Loc),
-             Parameter_Associations =>
-               New_List (
-                 Unchecked_Convert_To (RTE (RE_Tag), Concval),
-                 Make_Integer_Literal (Loc, DT_Position (Entity (Ename))))));
+                  Make_Integer_Literal (Loc, DT_Position (Entity (Ename))))));
+         end if;
 
-         --  Specific actuals for protected to interface class-wide type
-         --  requeue.
+         --  Specific actuals for protected to XXX requeue
 
          if Is_Protected_Type (Old_Typ) then
             Prepend_To (Params,
               Make_Attribute_Reference (Loc,        --  _object'Address
                 Prefix =>
                   Concurrent_Ref (New_Occurrence_Of (Old_Typ, Loc)),
-                Attribute_Name =>
-                  Name_Address));
+                Attribute_Name => Name_Address));
+
             Prepend_To (Params,                     --  True
               New_Reference_To (Standard_True, Loc));
 
-         --  Specific actuals for task to interface class-wide type requeue
+         --  Specific actuals for task to XXX requeue
 
          else
             pragma Assert (Is_Task_Type (Old_Typ));
 
             Prepend_To (Params,                     --  null
               New_Reference_To (RTE (RE_Null_Address), Loc));
+
             Prepend_To (Params,                     --  False
               New_Reference_To (Standard_False, Loc));
          end if;
 
-         --  Finally, add the common object parameter
+         --  Add the object parameter
 
          Prepend_To (Params, New_Copy_Tree (Concval));
 
-      --  Regular requeue processing
+         --  Generate:
+         --    _Disp_Requeue (<Params>);
 
-      else
-         New_Param := Concurrent_Ref (Concval);
+         return
+           Make_Procedure_Call_Statement (Loc,
+             Name => Make_Identifier (Loc, Name_uDisp_Requeue),
+             Parameter_Associations => Params);
+      end Build_Dispatching_Requeue;
+
+      --------------------------------------
+      -- Build_Dispatching_Requeue_To_Any --
+      --------------------------------------
+
+      function Build_Dispatching_Requeue_To_Any return Node_Id is
+         Call_Ent : constant Entity_Id := Entity (Ename);
+         Obj      : constant Node_Id   := Original_Node (Concval);
+         Skip     : constant Node_Id   := Build_Skip_Statement (N);
+         C        : Entity_Id;
+         Decls    : List_Id;
+         S        : Entity_Id;
+         Stmts    : List_Id;
+
+      begin
+         Decls := New_List;
+         Stmts := New_List;
+
+         --  Dispatch table slot processing, generate:
+         --    S : Integer;
+
+         S := Build_S (Loc, Decls);
+
+         --  Call kind processing, generate:
+         --    C : Ada.Tags.Prim_Op_Kind;
+
+         C := Build_C (Loc, Decls);
+
+         --  Generate:
+         --    S := Ada.Tags.Get_Offset_Index
+         --           (Ada.Tags.Tag (Obj), DT_Position (Call_Ent));
+
+         Append_To (Stmts, Build_S_Assignment (Loc, S, Obj, Call_Ent));
+
+         --  Generate:
+         --    _Disp_Get_Prim_Op_Kind (Obj, S, C);
+
+         Append_To (Stmts,
+           Make_Procedure_Call_Statement (Loc,
+             Name =>
+               New_Reference_To (
+                 Find_Prim_Op (Etype (Etype (Obj)),
+                   Name_uDisp_Get_Prim_Op_Kind),
+                 Loc),
+             Parameter_Associations => New_List (
+               New_Copy_Tree (Obj),
+               New_Reference_To (S, Loc),
+               New_Reference_To (C, Loc))));
+
+         Append_To (Stmts,
+
+            --  if C = POK_Protected_Entry
+            --    or else C = POK_Task_Entry
+            --  then
+
+           Make_If_Statement (Loc,
+             Condition =>
+               Make_Op_Or (Loc,
+                 Left_Opnd =>
+                   Make_Op_Eq (Loc,
+                     Left_Opnd =>
+                       New_Reference_To (C, Loc),
+                     Right_Opnd =>
+                       New_Reference_To (RTE (RE_POK_Protected_Entry), Loc)),
+
+                 Right_Opnd =>
+                   Make_Op_Eq (Loc,
+                     Left_Opnd =>
+                       New_Reference_To (C, Loc),
+                     Right_Opnd =>
+                       New_Reference_To (RTE (RE_POK_Task_Entry), Loc))),
+
+               --  Dispatching requeue equivalent
+
+             Then_Statements => New_List (
+               Build_Dispatching_Requeue,
+               Skip),
+
+               --  elsif C = POK_Protected_Procedure then
+
+             Elsif_Parts => New_List (
+               Make_Elsif_Part (Loc,
+                 Condition =>
+                   Make_Op_Eq (Loc,
+                     Left_Opnd =>
+                       New_Reference_To (C, Loc),
+                     Right_Opnd =>
+                       New_Reference_To (
+                         RTE (RE_POK_Protected_Procedure), Loc)),
+
+                  --  Dispatching call equivalent
+
+                 Then_Statements => New_List (
+                   Build_Dispatching_Call_Equivalent))),
+
+            --  else
+            --     raise Program_Error;
+            --  end if;
+
+             Else_Statements => New_List (
+               Make_Raise_Program_Error (Loc,
+                 Reason => PE_Explicit_Raise))));
+
+         --  Wrap everything into a block
+
+         return
+           Make_Block_Statement (Loc,
+             Declarations => Decls,
+             Handled_Statement_Sequence =>
+               Make_Handled_Sequence_Of_Statements (Loc,
+                 Statements => Stmts));
+      end Build_Dispatching_Requeue_To_Any;
+
+      --------------------------
+      -- Build_Normal_Requeue --
+      --------------------------
+
+      function Build_Normal_Requeue return Node_Id is
+         Params  : constant List_Id := New_List;
+         Param   : Node_Id;
+         RT_Call : Node_Id;
+
+      begin
+         --  Process the "with abort" parameter
+
+         Prepend_To (Params,
+           New_Reference_To (Boolean_Literals (Abort_Present (N)), Loc));
 
-         --  The index expression is common among all four cases
+         --  Add the index expression to the parameters. It is common among all
+         --  four cases.
 
          Prepend_To (Params,
            Entry_Index_Expression (Loc, Entity (Ename), Index, Conc_Typ));
 
          if Is_Protected_Type (Old_Typ) then
-            Self_Param :=
-              Make_Attribute_Reference (Loc,
-                Prefix =>
-                  Concurrent_Ref (New_Occurrence_Of (Old_Typ, Loc)),
-                Attribute_Name =>
-                  Name_Unchecked_Access);
-
-            --  Protected to protected requeue
-
-            if Is_Protected_Type (Conc_Typ) then
-               RTS_Call :=
-                 New_Reference_To (RTE (RE_Requeue_Protected_Entry), Loc);
+            declare
+               Self_Param : Node_Id;
 
-               New_Param :=
+            begin
+               Self_Param :=
                  Make_Attribute_Reference (Loc,
                    Prefix =>
-                     New_Param,
+                     Concurrent_Ref (New_Occurrence_Of (Old_Typ, Loc)),
                    Attribute_Name =>
                      Name_Unchecked_Access);
 
-            --  Protected to task requeue
+               --  Protected to protected requeue
 
-            else
-               pragma Assert (Is_Task_Type (Conc_Typ));
-               RTS_Call :=
-                 New_Reference_To (
-                   RTE (RE_Requeue_Protected_To_Task_Entry), Loc);
-            end if;
+               if Is_Protected_Type (Conc_Typ) then
+                  RT_Call :=
+                    New_Reference_To (
+                      RTE (RE_Requeue_Protected_Entry), Loc);
+
+                  Param :=
+                    Make_Attribute_Reference (Loc,
+                      Prefix =>
+                        Concurrent_Ref (Concval),
+                      Attribute_Name =>
+                        Name_Unchecked_Access);
 
-            Prepend (New_Param, Params);
-            Prepend (Self_Param, Params);
+               --  Protected to task requeue
 
-         else
-            pragma Assert (Is_Task_Type (Old_Typ));
+               else pragma Assert (Is_Task_Type (Conc_Typ));
+                  RT_Call :=
+                    New_Reference_To (
+                      RTE (RE_Requeue_Protected_To_Task_Entry), Loc);
+
+                  Param := Concurrent_Ref (Concval);
+               end if;
+
+               Prepend_To (Params, Param);
+               Prepend_To (Params, Self_Param);
+            end;
+
+         else pragma Assert (Is_Task_Type (Old_Typ));
 
             --  Task to protected requeue
 
             if Is_Protected_Type (Conc_Typ) then
-               RTS_Call :=
+               RT_Call :=
                  New_Reference_To (
                    RTE (RE_Requeue_Task_To_Protected_Entry), Loc);
 
-               New_Param :=
+               Param :=
                  Make_Attribute_Reference (Loc,
                    Prefix =>
-                     New_Param,
+                     Concurrent_Ref (Concval),
                    Attribute_Name =>
                      Name_Unchecked_Access);
 
             --  Task to task requeue
 
-            else
-               pragma Assert (Is_Task_Type (Conc_Typ));
-               RTS_Call :=
+            else pragma Assert (Is_Task_Type (Conc_Typ));
+               RT_Call :=
                  New_Reference_To (RTE (RE_Requeue_Task_Entry), Loc);
+
+               Param := Concurrent_Ref (Concval);
             end if;
 
-            Prepend (New_Param, Params);
+            Prepend_To (Params, Param);
          end if;
-      end if;
-
-      --  Create the GNARLI or predefined primitive call
 
-      Rcall :=
-        Make_Procedure_Call_Statement (Loc,
-          Name => RTS_Call,
-          Parameter_Associations => Params);
+         return
+            Make_Procedure_Call_Statement (Loc,
+              Name => RT_Call,
+              Parameter_Associations => Params);
+      end Build_Normal_Requeue;
 
-      Rewrite (N, Rcall);
-      Analyze (N);
+      --------------------------
+      -- Build_Skip_Statement --
+      --------------------------
 
-      if Is_Protected_Type (Old_Typ) then
+      function Build_Skip_Statement (Search : Node_Id) return Node_Id is
+         Skip_Stmt : Node_Id;
 
-         --  Build the return statement to skip the rest of the entry body
+      begin
+         --  Build a return statement to skip the rest of the entire body
 
-         Skip_Stat := Make_Simple_Return_Statement (Loc);
+         if Is_Protected_Type (Old_Typ) then
+            Skip_Stmt := Make_Simple_Return_Statement (Loc);
 
-      else
          --  If the requeue is within a task, find the end label of the
-         --  enclosing accept statement.
+         --  enclosing accept statement and create a goto statement to it.
 
-         Acc_Stat := Parent (N);
-         while Nkind (Acc_Stat) /= N_Accept_Statement loop
-            Acc_Stat := Parent (Acc_Stat);
-         end loop;
+         else
+            declare
+               Acc   : Node_Id;
+               Label : Node_Id;
 
-         --  The last statement is the second label, used for completing the
-         --  rendezvous the usual way. The label we are looking for is right
-         --  before it.
+            begin
+               --  Climb the parent chain looking for the enclosing accept
+               --  statement.
+
+               Acc := Parent (Search);
+               while Present (Acc)
+                 and then Nkind (Acc) /= N_Accept_Statement
+               loop
+                  Acc := Parent (Acc);
+               end loop;
 
-         Lab_Node :=
-           Prev (Last (Statements (Handled_Statement_Sequence (Acc_Stat))));
+               --  The last statement is the second label used for completing
+               --  the rendezvous the usual way. The label we are looking for
+               --  is right before it.
 
-         pragma Assert (Nkind (Lab_Node) = N_Label);
+               Label :=
+                 Prev (Last (Statements (Handled_Statement_Sequence (Acc))));
 
-         --  Build the goto statement to skip the rest of the accept
-         --  statement.
+               pragma Assert (Nkind (Label) = N_Label);
 
-         Skip_Stat :=
-           Make_Goto_Statement (Loc,
-             Name => New_Occurrence_Of (Entity (Identifier (Lab_Node)), Loc));
-      end if;
+               --  Generate a goto statement to skip the rest of the accept
+
+               Skip_Stmt :=
+                 Make_Goto_Statement (Loc,
+                   Name =>
+                     New_Occurrence_Of (Entity (Identifier (Label)), Loc));
+            end;
+         end if;
+
+         Set_Analyzed (Skip_Stmt);
+
+         return Skip_Stmt;
+      end Build_Skip_Statement;
+
+   --  Start of processing for Expand_N_Requeue_Statement
+
+   begin
+      --  Extract the components of the entry call
+
+      Extract_Entry (N, Concval, Ename, Index);
+      Conc_Typ := Etype (Concval);
+
+      --  Examine the scope stack in order to find nearest enclosing protected
+      --  or task type. This will constitute our invocation source.
+
+      Old_Typ := Current_Scope;
+      while Present (Old_Typ)
+        and then not Is_Protected_Type (Old_Typ)
+        and then not Is_Task_Type (Old_Typ)
+      loop
+         Old_Typ := Scope (Old_Typ);
+      end loop;
+
+      --  Ada 2012 (AI05-0030): We have a dispatching requeue of the form
+      --  Concval.Ename where the type of Concval is class-wide concurrent
+      --  interface.
+
+      if Ada_Version >= Ada_2012
+        and then Present (Concval)
+        and then Is_Class_Wide_Type (Conc_Typ)
+        and then Is_Concurrent_Interface (Conc_Typ)
+      then
+         declare
+            Has_Impl  : Boolean := False;
+            Impl_Kind : Name_Id := No_Name;
+
+         begin
+            --  Check whether the Ename is flagged by pragma Implemented
+
+            if Has_Rep_Pragma (Entity (Ename), Name_Implemented) then
+               Has_Impl  := True;
+               Impl_Kind := Implementation_Kind (Entity (Ename));
+            end if;
+
+            --  The procedure_or_entry_NAME is guaranteed to be overridden by
+            --  an entry. Create a call to predefined primitive _Disp_Requeue.
+
+            if Has_Impl
+              and then Impl_Kind = Name_By_Entry
+            then
+               Rewrite (N, Build_Dispatching_Requeue);
+               Analyze (N);
+               Insert_After (N, Build_Skip_Statement (N));
+
+            --  The procedure_or_entry_NAME is guaranteed to be overridden by
+            --  a protected procedure. In this case the requeue is transformed
+            --  into a dispatching call.
+
+            elsif Has_Impl
+              and then Impl_Kind = Name_By_Protected_Procedure
+            then
+               Rewrite (N, Build_Dispatching_Call_Equivalent);
+               Analyze (N);
+
+            --  The procedure_or_entry_NAME's implementation kind is either
+            --  By_Any or pragma Implemented was not applied at all. In this
+            --  case a runtime test determines whether Ename denotes an entry
+            --  or a protected procedure and performs the appropriate call.
+
+            else
+               Rewrite (N, Build_Dispatching_Requeue_To_Any);
+               Analyze (N);
+            end if;
+         end;
 
-      Set_Analyzed (Skip_Stat);
+      --  Processing for regular (non-dispatching) requeues
 
-      Insert_After (N, Skip_Stat);
+      else
+         Rewrite (N, Build_Normal_Requeue);
+         Analyze (N);
+         Insert_After (N, Build_Skip_Statement (N));
+      end if;
    end Expand_N_Requeue_Statement;
 
    -------------------------------
@@ -8108,8 +9533,7 @@ package body Exp_Ch9 is
       function Accept_Or_Raise return List_Id is
          Cond  : Node_Id;
          Stats : List_Id;
-         J     : constant Entity_Id := Make_Defining_Identifier (Loc,
-                                                  New_Internal_Name ('J'));
+         J     : constant Entity_Id := Make_Temporary (Loc, 'J');
 
       begin
          --  We generate the following:
@@ -8132,10 +9556,11 @@ package body Exp_Ch9 is
          Cond := Make_Op_Ne (Loc,
            Left_Opnd =>
              Make_Selected_Component (Loc,
-               Prefix => Make_Indexed_Component (Loc,
-                 Prefix => New_Reference_To (Qnam, Loc),
-                   Expressions => New_List (New_Reference_To (J, Loc))),
-             Selector_Name => Make_Identifier (Loc, Name_S)),
+               Prefix        =>
+                 Make_Indexed_Component (Loc,
+                   Prefix => New_Reference_To (Qnam, Loc),
+                     Expressions => New_List (New_Reference_To (J, Loc))),
+               Selector_Name => Make_Identifier (Loc, Name_S)),
            Right_Opnd =>
              New_Reference_To (RTE (RE_Null_Task_Entry), Loc));
 
@@ -8180,6 +9605,7 @@ package body Exp_Ch9 is
       procedure Add_Accept (Alt : Node_Id) is
          Acc_Stm   : constant Node_Id    := Accept_Statement (Alt);
          Ename     : constant Node_Id    := Entry_Direct_Name (Acc_Stm);
+         Eloc      : constant Source_Ptr := Sloc (Ename);
          Eent      : constant Entity_Id  := Entity (Ename);
          Index     : constant Node_Id    := Entry_Index (Acc_Stm);
          Null_Body : Node_Id;
@@ -8195,29 +9621,29 @@ package body Exp_Ch9 is
 
          if Present (Condition (Alt)) then
             Expr :=
-              Make_Conditional_Expression (Loc, New_List (
+              Make_Conditional_Expression (Eloc, New_List (
                 Condition (Alt),
-                Entry_Index_Expression (Loc, Eent, Index, Scope (Eent)),
-                New_Reference_To (RTE (RE_Null_Task_Entry), Loc)));
+                Entry_Index_Expression (Eloc, Eent, Index, Scope (Eent)),
+                New_Reference_To (RTE (RE_Null_Task_Entry), Eloc)));
          else
             Expr :=
               Entry_Index_Expression
-                (Loc, Eent, Index, Scope (Eent));
+                (Eloc, Eent, Index, Scope (Eent));
          end if;
 
          if Present (Handled_Statement_Sequence (Accept_Statement (Alt))) then
-            Null_Body := New_Reference_To (Standard_False, Loc);
+            Null_Body := New_Reference_To (Standard_False, Eloc);
 
             if Abort_Allowed then
-               Call := Make_Procedure_Call_Statement (Loc,
-                 Name => New_Reference_To (RTE (RE_Abort_Undefer), Loc));
+               Call := Make_Procedure_Call_Statement (Eloc,
+                 Name => New_Reference_To (RTE (RE_Abort_Undefer), Eloc));
                Insert_Before (First (Statements (Handled_Statement_Sequence (
                  Accept_Statement (Alt)))), Call);
                Analyze (Call);
             end if;
 
             PB_Ent :=
-              Make_Defining_Identifier (Sloc (Ename),
+              Make_Defining_Identifier (Eloc,
                 New_External_Name (Chars (Ename), 'A', Num_Accept));
 
             if Comes_From_Source (Alt) then
@@ -8225,9 +9651,9 @@ package body Exp_Ch9 is
             end if;
 
             Proc_Body :=
-              Make_Subprogram_Body (Loc,
+              Make_Subprogram_Body (Eloc,
                 Specification =>
-                  Make_Procedure_Specification (Loc,
+                  Make_Procedure_Specification (Eloc,
                     Defining_Unit_Name => PB_Ent),
                Declarations => Declarations (Acc_Stm),
                Handled_Statement_Sequence =>
@@ -8243,7 +9669,7 @@ package body Exp_Ch9 is
             Append (Proc_Body, Body_List);
 
          else
-            Null_Body := New_Reference_To (Standard_True,  Loc);
+            Null_Body := New_Reference_To (Standard_True,  Eloc);
 
             --  if accept statement has declarations, insert above, given that
             --  we are not creating a body for the accept.
@@ -8254,7 +9680,7 @@ package body Exp_Ch9 is
          end if;
 
          Append_To (Accept_List,
-           Make_Aggregate (Loc, Expressions => New_List (Null_Body, Expr)));
+           Make_Aggregate (Eloc, Expressions => New_List (Null_Body, Expr)));
 
          Num_Accept := Num_Accept + 1;
       end Add_Accept;
@@ -8324,9 +9750,9 @@ package body Exp_Ch9 is
               Make_Integer_Literal (Loc, Index));
 
             Alt_Stats := New_List (
-              Make_Procedure_Call_Statement (Loc,
+              Make_Procedure_Call_Statement (Sloc (Proc),
                 Name => New_Reference_To (
-                  Defining_Unit_Name (Specification (Proc)), Loc)));
+                  Defining_Unit_Name (Specification (Proc)), Sloc (Proc))));
          end if;
 
          if Statements (Alt) /= Empty_List then
@@ -8341,7 +9767,7 @@ package body Exp_Ch9 is
                Alt_Stats := New_List;
             end if;
 
-            --  After the call, if any, branch to to trailing statements. We
+            --  After the call, if any, branch to trailing statements. We
             --  create a label for each, as well as the corresponding label
             --  declaration.
 
@@ -8510,6 +9936,8 @@ package body Exp_Ch9 is
    --  Start of processing for Expand_N_Selective_Accept
 
    begin
+      Process_Statements_For_Controlled_Objects (N);
+
       --  First insert some declarations before the select. The first is:
 
       --    Ann : Address
@@ -8529,6 +9957,7 @@ package body Exp_Ch9 is
 
       Alt := First (Alts);
       while Present (Alt) loop
+         Process_Statements_For_Controlled_Objects (Alt);
 
          if Nkind (Alt) = N_Accept_Alternative then
             Add_Accept (Alt);
@@ -8700,8 +10129,8 @@ package body Exp_Ch9 is
          --  Create Duration and Delay_Mode objects used for passing a delay
          --  value to RTS
 
-         D := Make_Defining_Identifier (Loc, New_Internal_Name ('D'));
-         M := Make_Defining_Identifier (Loc, New_Internal_Name ('M'));
+         D := Make_Temporary (Loc, 'D');
+         M := Make_Temporary (Loc, 'M');
 
          declare
             Discr : Entity_Id;
@@ -9133,6 +10562,9 @@ package body Exp_Ch9 is
       Call  : Node_Id;
       New_N : Node_Id;
 
+      Insert_Nod : Node_Id;
+      --  Used to determine the proper location of wrapper body insertions
+
    begin
       --  Add renaming declarations for discriminals and a declaration for the
       --  entry family index (if applicable).
@@ -9199,57 +10631,17 @@ package body Exp_Ch9 is
       end if;
 
       --  Ada 2005 (AI-345): Construct the primitive entry wrapper bodies after
-      --  the task body. At this point the entry specs have been created,
+      --  the task body. At this point all wrapper specs have been created,
       --  frozen and included in the dispatch table for the task type.
 
-      pragma Assert (Present (Corresponding_Record_Type (Ttyp)));
-
-      if Ada_Version >= Ada_05
-        and then Present (Task_Definition (Parent (Ttyp)))
-        and then Present (Abstract_Interfaces
-                          (Corresponding_Record_Type (Ttyp)))
-      then
-         declare
-            Current_Node : Node_Id;
-            Vis_Decl     : Node_Id :=
-              First (Visible_Declarations (Task_Definition (Parent (Ttyp))));
-            Wrap_Body    : Node_Id;
-
-         begin
-            if Nkind (Parent (N)) = N_Subunit then
-               Current_Node := Corresponding_Stub (Parent (N));
-            else
-               Current_Node := N;
-            end if;
-
-            --  Examine the visible declarations of the task type, looking for
-            --  an entry declaration. We do not consider entry families since
-            --  they cannot have dispatching operations, thus they do not need
-            --  entry wrappers.
-
-            while Present (Vis_Decl) loop
-               if Nkind (Vis_Decl) = N_Entry_Declaration
-                 and then Ekind (Defining_Identifier (Vis_Decl)) = E_Entry
-               then
-                  --  Create the specification of the wrapper
-
-                  Wrap_Body :=
-                    Build_Wrapper_Body (Loc,
-                      Proc_Nam => Defining_Identifier (Vis_Decl),
-                      Obj_Typ  => Corresponding_Record_Type (Ttyp),
-                      Formals  => Parameter_Specifications (Vis_Decl));
-
-                  if Wrap_Body /= Empty then
-                     Insert_After (Current_Node, Wrap_Body);
-                     Current_Node := Wrap_Body;
-
-                     Analyze (Wrap_Body);
-                  end if;
-               end if;
+      if Ada_Version >= Ada_2005 then
+         if Nkind (Parent (N)) = N_Subunit then
+            Insert_Nod := Corresponding_Stub (Parent (N));
+         else
+            Insert_Nod := N;
+         end if;
 
-               Next (Vis_Decl);
-            end loop;
-         end;
+         Build_Wrapper_Bodies (Loc, Ttyp, Insert_Nod);
       end if;
    end Expand_N_Task_Body;
 
@@ -9282,11 +10674,14 @@ package body Exp_Ch9 is
    --  values of this task. The general form of this type declaration is
 
    --    type taskV (discriminants) is record
-   --      _Task_Id     : Task_Id;
-   --      entry_family : array (bounds) of Void;
-   --      _Priority    : Integer         := priority_expression;
-   --      _Size        : Size_Type       := Size_Type (size_expression);
-   --      _Task_Info   : Task_Info_Type  := task_info_expression;
+   --      _Task_Id           : Task_Id;
+   --      entry_family       : array (bounds) of Void;
+   --      _Priority          : Integer            := priority_expression;
+   --      _Size              : Size_Type          := size_expression;
+   --      _Task_Info         : Task_Info_Type     := task_info_expression;
+   --      _CPU               : Integer            := cpu_range_expression;
+   --      _Relative_Deadline : Time_Span          := time_span_expression;
+   --      _Domain            : Dispatching_Domain := dd_expression;
    --    end record;
 
    --  The discriminants are present only if the corresponding task type has
@@ -9320,11 +10715,21 @@ package body Exp_Ch9 is
    --  present in the pragma, and is used to provide the Task_Image parameter
    --  to the call to Create_Task.
 
+   --  The _CPU field is present only if a CPU pragma appears in the task
+   --  definition. The expression captures the argument that was present in
+   --  the pragma, and is used to provide the CPU parameter to the call to
+   --  Create_Task.
+
    --  The _Relative_Deadline field is present only if a Relative_Deadline
    --  pragma appears in the task definition. The expression captures the
    --  argument that was present in the pragma, and is used to provide the
    --  Relative_Deadline parameter to the call to Create_Task.
 
+   --  The _Domain field is present only if a Dispatching_Domain pragma or
+   --  aspect appears in the task definition. The expression captures the
+   --  argument that was present in the pragma or aspect, and is used to
+   --  provide the Dispatching_Domain parameter to the call to Create_Task.
+
    --  When a task is declared, an instance of the task value record is
    --  created. The elaboration of this declaration creates the correct bounds
    --  for the entry families, and also evaluates the size, priority, and
@@ -9381,12 +10786,7 @@ package body Exp_Ch9 is
 
       --  Here we will do the expansion
 
-      Rec_Decl := Build_Corresponding_Record (N, Tasktyp, Loc);
-
-      --  Ada 2005 (AI-345): Propagate the attribute that contains the list
-      --  of implemented interfaces.
-
-      Set_Interface_List (Type_Definition (Rec_Decl), Interface_List (N));
+      Rec_Decl := Build_Corresponding_Record (N, Tasktyp, Loc);
 
       Rec_Ent  := Defining_Identifier (Rec_Decl);
       Cdecls   := Component_Items (Component_List
@@ -9412,29 +10812,34 @@ package body Exp_Ch9 is
         Make_Defining_Identifier (Sloc (Tasktyp),
           Chars => New_External_Name (Tasknm, 'Z')));
 
-      if Present (Taskdef) and then Has_Storage_Size_Pragma (Taskdef) and then
-        Is_Static_Expression (Expression (First (
-          Pragma_Argument_Associations (Find_Task_Or_Protected_Pragma (
-            Taskdef, Name_Storage_Size)))))
+      if Present (Taskdef)
+        and then Has_Storage_Size_Pragma (Taskdef)
+        and then
+          Is_Static_Expression
+            (Expression
+               (First (Pragma_Argument_Associations
+                         (Find_Task_Or_Protected_Pragma
+                            (Taskdef, Name_Storage_Size)))))
       then
          Size_Decl :=
            Make_Object_Declaration (Loc,
              Defining_Identifier => Storage_Size_Variable (Tasktyp),
-             Object_Definition => New_Reference_To (RTE (RE_Size_Type), Loc),
-             Expression =>
+             Object_Definition   => New_Reference_To (RTE (RE_Size_Type), Loc),
+             Expression          =>
                Convert_To (RTE (RE_Size_Type),
-                 Relocate_Node (
-                   Expression (First (
-                     Pragma_Argument_Associations (
-                       Find_Task_Or_Protected_Pragma
-                         (Taskdef, Name_Storage_Size)))))));
+                 Relocate_Node
+                   (Expression (First (Pragma_Argument_Associations
+                                         (Find_Task_Or_Protected_Pragma
+                                            (Taskdef, Name_Storage_Size)))))));
 
       else
          Size_Decl :=
            Make_Object_Declaration (Loc,
              Defining_Identifier => Storage_Size_Variable (Tasktyp),
-             Object_Definition => New_Reference_To (RTE (RE_Size_Type), Loc),
-             Expression => New_Reference_To (RTE (RE_Unspecified_Size), Loc));
+             Object_Definition   =>
+               New_Reference_To (RTE (RE_Size_Type), Loc),
+             Expression          =>
+               New_Reference_To (RTE (RE_Unspecified_Size), Loc));
       end if;
 
       Insert_After (Elab_Decl, Size_Decl);
@@ -9447,7 +10852,7 @@ package body Exp_Ch9 is
 
       Append_To (Cdecls,
         Make_Component_Declaration (Loc,
-          Defining_Identifier =>
+          Defining_Identifier  =>
             Make_Defining_Identifier (Loc, Name_uTask_Id),
           Component_Definition =>
             Make_Component_Definition (Loc,
@@ -9468,8 +10873,8 @@ package body Exp_Ch9 is
                Make_Component_Definition (Loc,
                  Aliased_Present     => True,
                  Subtype_Indication  => Make_Subtype_Indication (Loc,
-                   Subtype_Mark => New_Occurrence_Of
-                     (RTE (RE_Ada_Task_Control_Block), Loc),
+                   Subtype_Mark =>
+                     New_Occurrence_Of (RTE (RE_Ada_Task_Control_Block), Loc),
 
                    Constraint   =>
                      Make_Index_Or_Discriminant_Constraint (Loc,
@@ -9555,7 +10960,7 @@ package body Exp_Ch9 is
 
       --  Add the _Priority component if a Priority pragma is present
 
-      if Present (Taskdef) and then Has_Priority_Pragma (Taskdef) then
+      if Present (Taskdef) and then Has_Pragma_Priority (Taskdef) then
          declare
             Prag : constant Node_Id :=
                      Find_Task_Or_Protected_Pragma (Taskdef, Name_Priority);
@@ -9643,6 +11048,27 @@ package body Exp_Ch9 is
                      (Taskdef, Name_Task_Info)))))));
       end if;
 
+      --  Add the _CPU component if a CPU pragma is present
+
+      if Present (Taskdef) and then Has_Pragma_CPU (Taskdef) then
+         Append_To (Cdecls,
+           Make_Component_Declaration (Loc,
+             Defining_Identifier =>
+               Make_Defining_Identifier (Loc, Name_uCPU),
+
+             Component_Definition =>
+               Make_Component_Definition (Loc,
+                 Aliased_Present    => False,
+                 Subtype_Indication =>
+                   New_Reference_To (RTE (RE_CPU_Range), Loc)),
+
+             Expression => New_Copy (
+               Expression (First (
+                 Pragma_Argument_Associations (
+                   Find_Task_Or_Protected_Pragma
+                     (Taskdef, Name_CPU)))))));
+      end if;
+
       --  Add the _Relative_Deadline component if a Relative_Deadline pragma is
       --  present. If we are using a restricted run time this component will
       --  not be added (deadlines are not allowed by the Ravenscar profile).
@@ -9671,6 +11097,37 @@ package body Exp_Ch9 is
                          (Taskdef, Name_Relative_Deadline))))))));
       end if;
 
+      --  Add the _Dispatching_Domain component if a Dispatching_Domain pragma
+      --  or aspect is present. If we are using a restricted run time this
+      --  component will not be added (dispatching domains are not allowed by
+      --  the Ravenscar profile).
+
+      if not Restricted_Profile
+        and then Present (Taskdef)
+        and then Has_Pragma_Dispatching_Domain (Taskdef)
+      then
+         Append_To (Cdecls,
+           Make_Component_Declaration (Loc,
+             Defining_Identifier  =>
+               Make_Defining_Identifier (Loc, Name_uDispatching_Domain),
+
+             Component_Definition =>
+               Make_Component_Definition (Loc,
+                 Aliased_Present    => False,
+                 Subtype_Indication =>
+                   New_Reference_To
+                     (RTE (RE_Dispatching_Domain_Access), Loc)),
+
+             Expression           =>
+               Unchecked_Convert_To (RTE (RE_Dispatching_Domain_Access),
+                 Relocate_Node
+                   (Expression
+                      (First
+                         (Pragma_Argument_Associations
+                            (Find_Task_Or_Protected_Pragma
+                               (Taskdef, Name_Dispatching_Domain))))))));
+      end if;
+
       Insert_After (Size_Decl, Rec_Decl);
 
       --  Analyze the record declaration immediately after construction,
@@ -9698,51 +11155,8 @@ package body Exp_Ch9 is
       --  Ada 2005 (AI-345): Construct the primitive entry wrapper specs before
       --  the corresponding record has been frozen.
 
-      if Ada_Version >= Ada_05
-        and then Present (Taskdef)
-        and then Present (Corresponding_Record_Type
-                          (Defining_Identifier (Parent (Taskdef))))
-        and then Present (Abstract_Interfaces
-                          (Corresponding_Record_Type
-                           (Defining_Identifier (Parent (Taskdef)))))
-      then
-         declare
-            Current_Node : Node_Id := Rec_Decl;
-            Vis_Decl     : Node_Id := First (Visible_Declarations (Taskdef));
-            Wrap_Spec    : Node_Id;
-            New_N        : Node_Id;
-
-         begin
-            --  Examine the visible declarations of the task type, looking for
-            --  an entry declaration. We do not consider entry families since
-            --  they cannot have dispatching operations, thus they do not need
-            --  entry wrappers.
-
-            while Present (Vis_Decl) loop
-               if Nkind (Vis_Decl) = N_Entry_Declaration
-                 and then Ekind (Defining_Identifier (Vis_Decl)) = E_Entry
-               then
-                  Wrap_Spec :=
-                    Build_Wrapper_Spec (Loc,
-                      Proc_Nam => Defining_Identifier (Vis_Decl),
-                      Obj_Typ  => Etype (Rec_Ent),
-                      Formals  => Parameter_Specifications (Vis_Decl));
-
-                  if Wrap_Spec /= Empty then
-                     New_N :=
-                       Make_Subprogram_Declaration (Loc,
-                         Specification => Wrap_Spec);
-
-                     Insert_After (Current_Node, New_N);
-                     Current_Node := New_N;
-
-                     Analyze (New_N);
-                  end if;
-               end if;
-
-               Next (Vis_Decl);
-            end loop;
-         end;
+      if Ada_Version >= Ada_2005 then
+         Build_Wrapper_Specs (Loc, Tasktyp, Rec_Decl);
       end if;
 
       --  Ada 2005 (AI-345): We must defer freezing to allow further
@@ -9757,8 +11171,7 @@ package body Exp_Ch9 is
          --  in time if we don't freeze now.
 
          declare
-            L : constant List_Id := Freeze_Entity (Rec_Ent, Loc);
-
+            L : constant List_Id := Freeze_Entity (Rec_Ent, N);
          begin
             if Is_Non_Empty_List (L) then
                Insert_List_After (Body_Decl, L);
@@ -9770,6 +11183,24 @@ package body Exp_Ch9 is
       --  any were declared.
 
       Expand_Previous_Access_Type (Tasktyp);
+
+      --  Create wrappers for entries that have pre/postconditions
+
+      declare
+         Ent : Entity_Id;
+
+      begin
+         Ent := First_Entity (Tasktyp);
+         while Present (Ent) loop
+            if Ekind_In (Ent, E_Entry, E_Entry_Family)
+              and then Present (Spec_PPC_List (Contract (Ent)))
+            then
+               Build_PPC_Wrapper (Ent, N);
+            end if;
+
+            Next_Entity (Ent);
+         end loop;
+      end;
    end Expand_N_Task_Type_Declaration;
 
    -------------------------------
@@ -9837,7 +11268,7 @@ package body Exp_Ch9 is
    --              Ada.Tags.Get_Tagged_Kind (Ada.Tags.Tag (<object>));
    --       M  : Integer :=...;
    --       P  : Parameters := (Param1 .. ParamN);
-   --       S  : Iteger;
+   --       S  : Integer;
 
    --    begin
    --       if K = Ada.Tags.TK_Limited_Tagged then
@@ -9874,6 +11305,11 @@ package body Exp_Ch9 is
    --       end if;
    --    end;
 
+   --  The triggering statement and the sequence of timed statements have not
+   --  been analyzed yet (see Analyzed_Timed_Entry_Call). They may contain
+   --  local declarations, and therefore the copies that are made during
+   --  expansion must be disjoint, as for any other inlining.
+
    procedure Expand_N_Timed_Entry_Call (N : Node_Id) is
       Loc : constant Source_Ptr := Sloc (N);
 
@@ -9919,6 +11355,16 @@ package body Exp_Ch9 is
       S : Entity_Id;  --  Primitive operation slot
 
    begin
+      --  Under the Ravenscar profile, timed entry calls are excluded. An error
+      --  was already reported on spec, so do not attempt to expand the call.
+
+      if Restriction_Active (No_Select_Statements) then
+         return;
+      end if;
+
+      Process_Statements_For_Controlled_Objects (Entry_Call_Alternative (N));
+      Process_Statements_For_Controlled_Objects (Delay_Alternative (N));
+
       --  The arguments in the call may require dynamic allocation, and the
       --  call statement may have been transformed into a block. The block
       --  may contain additional declarations for internal entities, and the
@@ -9934,7 +11380,7 @@ package body Exp_Ch9 is
       end if;
 
       Is_Disp_Select :=
-        Ada_Version >= Ada_05
+        Ada_Version >= Ada_2005
           and then Nkind (E_Call) = N_Procedure_Call_Statement;
 
       if Is_Disp_Select then
@@ -9979,10 +11425,8 @@ package body Exp_Ch9 is
 
          Prepend_To (Decls,
            Make_Object_Declaration (Loc,
-             Defining_Identifier =>
-               B,
-             Object_Definition =>
-               New_Reference_To (Standard_Boolean, Loc)));
+             Defining_Identifier => B,
+             Object_Definition   => New_Reference_To (Standard_Boolean, Loc)));
       end if;
 
       --  Duration and mode processing
@@ -9998,52 +11442,49 @@ package body Exp_Ch9 is
 
       elsif Is_RTE (D_Type, RO_CA_Time) then
          D_Disc := Make_Integer_Literal (Loc, 1);
-         D_Conv := Make_Function_Call (Loc,
-           New_Reference_To (RTE (RO_CA_To_Duration), Loc),
-           New_List (New_Copy (Expression (D_Stat))));
+         D_Conv :=
+           Make_Function_Call (Loc,
+             Name => New_Reference_To (RTE (RO_CA_To_Duration), Loc),
+             Parameter_Associations =>
+               New_List (New_Copy (Expression (D_Stat))));
 
       else pragma Assert (Is_RTE (D_Type, RO_RT_Time));
          D_Disc := Make_Integer_Literal (Loc, 2);
-         D_Conv := Make_Function_Call (Loc,
-           New_Reference_To (RTE (RO_RT_To_Duration), Loc),
-           New_List (New_Copy (Expression (D_Stat))));
+         D_Conv :=
+           Make_Function_Call (Loc,
+             Name => New_Reference_To (RTE (RO_RT_To_Duration), Loc),
+             Parameter_Associations =>
+               New_List (New_Copy (Expression (D_Stat))));
       end if;
 
-      D := Make_Defining_Identifier (Loc, New_Internal_Name ('D'));
+      D := Make_Temporary (Loc, 'D');
 
       --  Generate:
       --    D : Duration;
 
       Append_To (Decls,
         Make_Object_Declaration (Loc,
-          Defining_Identifier =>
-            D,
-          Object_Definition =>
-            New_Reference_To (Standard_Duration, Loc)));
+          Defining_Identifier => D,
+          Object_Definition   => New_Reference_To (Standard_Duration, Loc)));
 
-      M := Make_Defining_Identifier (Loc, New_Internal_Name ('M'));
+      M := Make_Temporary (Loc, 'M');
 
       --  Generate:
       --    M : Integer := (0 | 1 | 2);
 
       Append_To (Decls,
         Make_Object_Declaration (Loc,
-          Defining_Identifier =>
-            M,
-          Object_Definition =>
-            New_Reference_To (Standard_Integer, Loc),
-          Expression =>
-            D_Disc));
+          Defining_Identifier => M,
+          Object_Definition   => New_Reference_To (Standard_Integer, Loc),
+          Expression          => D_Disc));
 
       --  Do the assignment at this stage only because the evaluation of the
       --  expression must not occur before (see ACVC C97302A).
 
       Append_To (Stmts,
         Make_Assignment_Statement (Loc,
-          Name =>
-            New_Reference_To (D, Loc),
-          Expression =>
-            D_Conv));
+          Name       => New_Reference_To (D, Loc),
+          Expression => D_Conv));
 
       --  Parameter block processing
 
@@ -10060,8 +11501,8 @@ package body Exp_Ch9 is
          K := Build_K (Loc, Decls, Obj);
 
          Blk_Typ := Build_Parameter_Block (Loc, Actuals, Formals, Decls);
-         P := Parameter_Block_Pack
-                (Loc, Blk_Typ, Actuals, Formals, Decls, Stmts);
+         P :=
+           Parameter_Block_Pack (Loc, Blk_Typ, Actuals, Formals, Decls, Stmts);
 
          --  Dispatch table slot processing, generate:
          --    S : Integer;
@@ -10087,9 +11528,10 @@ package body Exp_Ch9 is
 
          Append_To (Params, New_Copy_Tree (Obj));
          Append_To (Params, New_Reference_To (S, Loc));
-         Append_To (Params, Make_Attribute_Reference (Loc,
-                              Prefix => New_Reference_To (P, Loc),
-                              Attribute_Name => Name_Address));
+         Append_To (Params,
+           Make_Attribute_Reference (Loc,
+             Prefix         => New_Reference_To (P, Loc),
+             Attribute_Name => Name_Address));
          Append_To (Params, New_Reference_To (D, Loc));
          Append_To (Params, New_Reference_To (M, Loc));
          Append_To (Params, New_Reference_To (C, Loc));
@@ -10098,12 +11540,10 @@ package body Exp_Ch9 is
          Append_To (Conc_Typ_Stmts,
            Make_Procedure_Call_Statement (Loc,
              Name =>
-               New_Reference_To (
-                 Find_Prim_Op (Etype (Etype (Obj)),
-                   Name_uDisp_Timed_Select),
-                 Loc),
-             Parameter_Associations =>
-               Params));
+               New_Reference_To
+                 (Find_Prim_Op
+                   (Etype (Etype (Obj)), Name_uDisp_Timed_Select), Loc),
+             Parameter_Associations => Params));
 
          --  Generate:
          --    if C = POK_Protected_Entry
@@ -10123,24 +11563,22 @@ package body Exp_Ch9 is
             Append_To (Conc_Typ_Stmts,
               Make_If_Statement (Loc,
 
-                Condition =>
+                Condition       =>
                   Make_Or_Else (Loc,
-                    Left_Opnd =>
+                    Left_Opnd  =>
                       Make_Op_Eq (Loc,
-                        Left_Opnd =>
-                          New_Reference_To (C, Loc),
+                        Left_Opnd => New_Reference_To (C, Loc),
                         Right_Opnd =>
-                          New_Reference_To (RTE (
-                            RE_POK_Protected_Entry), Loc)),
+                          New_Reference_To
+                            (RTE (RE_POK_Protected_Entry), Loc)),
+
                     Right_Opnd =>
                       Make_Op_Eq (Loc,
-                        Left_Opnd =>
-                          New_Reference_To (C, Loc),
+                        Left_Opnd  => New_Reference_To (C, Loc),
                         Right_Opnd =>
                           New_Reference_To (RTE (RE_POK_Task_Entry), Loc))),
 
-                Then_Statements =>
-                  Unpack));
+                Then_Statements => Unpack));
          end if;
 
          --  Generate:
@@ -10157,7 +11595,7 @@ package body Exp_Ch9 is
          --       <timed-statements>
          --    end if;
 
-         N_Stats := New_Copy_List_Tree (E_Stats);
+         N_Stats := Copy_Separate_List (E_Stats);
 
          Prepend_To (N_Stats,
            Make_If_Statement (Loc,
@@ -10166,33 +11604,30 @@ package body Exp_Ch9 is
                Make_Or_Else (Loc,
                  Left_Opnd =>
                    Make_Op_Eq (Loc,
-                     Left_Opnd =>
-                       New_Reference_To (C, Loc),
+                     Left_Opnd  => New_Reference_To (C, Loc),
                      Right_Opnd =>
                        New_Reference_To (RTE (RE_POK_Procedure), Loc)),
+
                  Right_Opnd =>
                    Make_Or_Else (Loc,
                      Left_Opnd =>
                        Make_Op_Eq (Loc,
-                         Left_Opnd =>
-                           New_Reference_To (C, Loc),
+                         Left_Opnd  => New_Reference_To (C, Loc),
                          Right_Opnd =>
                            New_Reference_To (RTE (
                              RE_POK_Protected_Procedure), Loc)),
                      Right_Opnd =>
                        Make_Op_Eq (Loc,
-                         Left_Opnd =>
-                           New_Reference_To (C, Loc),
+                         Left_Opnd  => New_Reference_To (C, Loc),
                          Right_Opnd =>
-                           New_Reference_To (RTE (
-                             RE_POK_Task_Procedure), Loc)))),
+                           New_Reference_To
+                             (RTE (RE_POK_Task_Procedure), Loc)))),
 
-             Then_Statements =>
-               New_List (E_Call)));
+             Then_Statements => New_List (E_Call)));
 
          Append_To (Conc_Typ_Stmts,
            Make_If_Statement (Loc,
-             Condition => New_Reference_To (B, Loc),
+             Condition       => New_Reference_To (B, Loc),
              Then_Statements => N_Stats,
              Else_Statements => D_Stats));
 
@@ -10200,7 +11635,7 @@ package body Exp_Ch9 is
          --    <dispatching-call>;
          --    <triggering-statements>
 
-         Lim_Typ_Stmts := New_Copy_List_Tree (E_Stats);
+         Lim_Typ_Stmts := Copy_Separate_List (E_Stats);
          Prepend_To (Lim_Typ_Stmts, New_Copy_Tree (E_Call));
 
          --  Generate:
@@ -10212,18 +11647,13 @@ package body Exp_Ch9 is
 
          Append_To (Stmts,
            Make_If_Statement (Loc,
-             Condition =>
+             Condition       =>
                Make_Op_Eq (Loc,
-                 Left_Opnd =>
-                   New_Reference_To (K, Loc),
+                 Left_Opnd  => New_Reference_To (K, Loc),
                  Right_Opnd =>
                    New_Reference_To (RTE (RE_TK_Limited_Tagged), Loc)),
-
-             Then_Statements =>
-               Lim_Typ_Stmts,
-
-             Else_Statements =>
-               Conc_Typ_Stmts));
+             Then_Statements => Lim_Typ_Stmts,
+             Else_Statements => Conc_Typ_Stmts));
 
       else
          --  Skip assignments to temporaries created for in-out parameters.
@@ -10240,7 +11670,7 @@ package body Exp_Ch9 is
 
          Insert_Before (Stmt,
            Make_Assignment_Statement (Loc,
-             Name => New_Reference_To (D, Loc),
+             Name       => New_Reference_To (D, Loc),
              Expression => D_Conv));
 
          Call   := Stmt;
@@ -10300,8 +11730,9 @@ package body Exp_Ch9 is
 
                   Rewrite (Call,
                     Make_Procedure_Call_Statement (Loc,
-                      Name => New_Reference_To (
-                        RTE (RE_Timed_Protected_Single_Entry_Call), Loc),
+                      Name =>
+                        New_Reference_To
+                          (RTE (RE_Timed_Protected_Single_Entry_Call), Loc),
                       Parameter_Associations => Params));
 
                when others =>
@@ -10326,14 +11757,14 @@ package body Exp_Ch9 is
 
          Append_To (Stmts,
            Make_Implicit_If_Statement (N,
-             Condition => New_Reference_To (B, Loc),
+             Condition       => New_Reference_To (B, Loc),
              Then_Statements => E_Stats,
              Else_Statements => D_Stats));
       end if;
 
       Rewrite (N,
         Make_Block_Statement (Loc,
-          Declarations => Decls,
+          Declarations               => Decls,
           Handled_Statement_Sequence =>
             Make_Handled_Sequence_Of_Statements (Loc, Stmts)));
 
@@ -10353,7 +11784,7 @@ package body Exp_Ch9 is
          Error_Msg_CRT ("protected body", N);
          return;
 
-      elsif Expander_Active then
+      elsif Full_Expander_Active then
 
          --  Associate discriminals with the first subprogram or entry body to
          --  be expanded.
@@ -10439,6 +11870,14 @@ package body Exp_Ch9 is
       if Present (Original_Node (Object)) then
          Object := Original_Node (Object);
       end if;
+
+      --  If the type of the dispatching object is an access type then return
+      --  an explicit dereference.
+
+      if Is_Access_Type (Etype (Object)) then
+         Object := Make_Explicit_Dereference (Sloc (N), Object);
+         Analyze (Object);
+      end if;
    end Extract_Dispatching_Call;
 
    -------------------
@@ -10608,6 +12047,131 @@ package body Exp_Ch9 is
             Make_Integer_Literal (Loc, 0)));
    end Family_Size;
 
+   ----------------------------
+   -- Find_Enclosing_Context --
+   ----------------------------
+
+   procedure Find_Enclosing_Context
+     (N             : Node_Id;
+      Context       : out Node_Id;
+      Context_Id    : out Entity_Id;
+      Context_Decls : out List_Id)
+   is
+   begin
+      --  Traverse the parent chain looking for an enclosing body, block,
+      --  package or return statement.
+
+      Context := Parent (N);
+      while not Nkind_In (Context, N_Block_Statement,
+                                   N_Entry_Body,
+                                   N_Extended_Return_Statement,
+                                   N_Package_Body,
+                                   N_Package_Declaration,
+                                   N_Subprogram_Body,
+                                   N_Task_Body)
+      loop
+         Context := Parent (Context);
+      end loop;
+
+      --  Extract the constituents of the context
+
+      if Nkind (Context) = N_Extended_Return_Statement then
+         Context_Decls := Return_Object_Declarations (Context);
+         Context_Id    := Return_Statement_Entity (Context);
+
+      --  Package declarations and bodies use a common library-level activation
+      --  chain or task master, therefore return the package declaration as the
+      --  proper carrier for the appropriate flag.
+
+      elsif Nkind (Context) = N_Package_Body then
+         Context_Decls := Declarations (Context);
+         Context_Id    := Corresponding_Spec (Context);
+         Context       := Parent (Context_Id);
+
+         if Nkind (Context) = N_Defining_Program_Unit_Name then
+            Context := Parent (Parent (Context));
+         else
+            Context := Parent (Context);
+         end if;
+
+      elsif Nkind (Context) = N_Package_Declaration then
+         Context_Decls := Visible_Declarations (Specification (Context));
+         Context_Id    := Defining_Unit_Name (Specification (Context));
+
+         if Nkind (Context_Id) = N_Defining_Program_Unit_Name then
+            Context_Id := Defining_Identifier (Context_Id);
+         end if;
+
+      else
+         Context_Decls := Declarations (Context);
+
+         if Nkind (Context) = N_Block_Statement then
+            Context_Id := Entity (Identifier (Context));
+
+         elsif Nkind (Context) = N_Entry_Body then
+            Context_Id := Defining_Identifier (Context);
+
+         elsif Nkind (Context) = N_Subprogram_Body then
+            if Present (Corresponding_Spec (Context)) then
+               Context_Id := Corresponding_Spec (Context);
+            else
+               Context_Id := Defining_Unit_Name (Specification (Context));
+
+               if Nkind (Context_Id) = N_Defining_Program_Unit_Name then
+                  Context_Id := Defining_Identifier (Context_Id);
+               end if;
+            end if;
+
+         elsif Nkind (Context) = N_Task_Body then
+            Context_Id := Corresponding_Spec (Context);
+
+         else
+            raise Program_Error;
+         end if;
+      end if;
+
+      pragma Assert (Present (Context));
+      pragma Assert (Present (Context_Id));
+      pragma Assert (Present (Context_Decls));
+   end Find_Enclosing_Context;
+
+   -----------------------
+   -- Find_Master_Scope --
+   -----------------------
+
+   function Find_Master_Scope (E : Entity_Id) return Entity_Id is
+      S : Entity_Id;
+
+   begin
+      --  In Ada 2005, the master is the innermost enclosing scope that is not
+      --  transient. If the enclosing block is the rewriting of a call or the
+      --  scope is an extended return statement this is valid master. The
+      --  master in an extended return is only used within the return, and is
+      --  subsequently overwritten in Move_Activation_Chain, but it must exist
+      --  now before that overwriting occurs.
+
+      S := Scope (E);
+
+      if Ada_Version >= Ada_2005 then
+         while Is_Internal (S) loop
+            if Nkind (Parent (S)) = N_Block_Statement
+              and then
+                Nkind (Original_Node (Parent (S))) = N_Procedure_Call_Statement
+            then
+               exit;
+
+            elsif Ekind (S) = E_Return_Statement then
+               exit;
+
+            else
+               S := Scope (S);
+            end if;
+         end loop;
+      end if;
+
+      return S;
+   end Find_Master_Scope;
+
    -----------------------------------
    -- Find_Task_Or_Protected_Pragma --
    -----------------------------------
@@ -10800,9 +12364,7 @@ package body Exp_Ch9 is
 
       if Is_Protected then
          declare
-            Prot_Ent : constant Entity_Id :=
-                         Make_Defining_Identifier (Loc,
-                           New_Internal_Name ('R'));
+            Prot_Ent : constant Entity_Id := Make_Temporary (Loc, 'R');
             Prot_Typ : RE_Id;
 
          begin
@@ -10812,10 +12374,13 @@ package body Exp_Ch9 is
 
             if Has_Attach_Handler (Conc_Typ)
               and then not Restricted_Profile
+              and then not Restriction_Active (No_Dynamic_Attachment)
             then
                Prot_Typ := RE_Static_Interrupt_Protection;
 
-            elsif Has_Interrupt_Handler (Conc_Typ) then
+            elsif Has_Interrupt_Handler (Conc_Typ)
+              and then not Restriction_Active (No_Dynamic_Attachment)
+            then
                Prot_Typ := RE_Dynamic_Interrupt_Protection;
 
             --  The type has explicit entries or generated primitive entry
@@ -10823,7 +12388,7 @@ package body Exp_Ch9 is
 
             elsif Has_Entries (Conc_Typ)
               or else
-                (Ada_Version >= Ada_05
+                (Ada_Version >= Ada_2005
                    and then Present (Interface_List (Parent (Conc_Typ))))
             then
                case Corresponding_Runtime_Package (Conc_Typ) is
@@ -10851,10 +12416,8 @@ package body Exp_Ch9 is
                   New_Reference_To (RTE (Prot_Typ), Loc),
                 Name =>
                   Make_Selected_Component (Loc,
-                    Prefix =>
-                      New_Reference_To (Obj_Ent, Loc),
-                    Selector_Name =>
-                      Make_Identifier (Loc, Name_uObject)));
+                    Prefix        => New_Reference_To (Obj_Ent, Loc),
+                    Selector_Name => Make_Identifier (Loc, Name_uObject)));
             Add (Decl);
          end;
       end if;
@@ -10991,8 +12554,7 @@ package body Exp_Ch9 is
                High := Replace_Bound (High);
                Low  := Replace_Bound (Low);
 
-               Index_Typ :=
-                 Make_Defining_Identifier (Loc, New_Internal_Name ('J'));
+               Index_Typ := Make_Temporary (Loc, 'J');
 
                --  Generate:
                --    subtype Jnn is <Etype of Index> range Low .. High;
@@ -11082,6 +12644,17 @@ package body Exp_Ch9 is
             or else Denotes_Discriminant (Hi, True));
    end Is_Potentially_Large_Family;
 
+   -------------------------------------
+   -- Is_Private_Primitive_Subprogram --
+   -------------------------------------
+
+   function Is_Private_Primitive_Subprogram (Id : Entity_Id) return Boolean is
+   begin
+      return
+        (Ekind (Id) = E_Function or else Ekind (Id) = E_Procedure)
+          and then Is_Private_Primitive (Id);
+   end Is_Private_Primitive_Subprogram;
+
    ------------------
    -- Index_Object --
    ------------------
@@ -11165,7 +12738,7 @@ package body Exp_Ch9 is
         Make_Attribute_Reference (Loc,
           Prefix =>
             Make_Selected_Component (Loc,
-              Prefix => Make_Identifier (Loc, Name_uInit),
+              Prefix        => Make_Identifier (Loc, Name_uInit),
               Selector_Name => Make_Identifier (Loc, Name_uObject)),
           Attribute_Name => Name_Unchecked_Access));
 
@@ -11176,7 +12749,7 @@ package body Exp_Ch9 is
       --  defined value, see D.3(10).
 
       if Present (Pdef)
-        and then Has_Priority_Pragma (Pdef)
+        and then Has_Pragma_Priority (Pdef)
       then
          declare
             Prio : constant Node_Id :=
@@ -11209,9 +12782,7 @@ package body Exp_Ch9 is
             --  Interrupt_Priority).
 
             else
-               Temp :=
-                 Make_Defining_Identifier (Loc, New_Internal_Name ('R'));
-
+               Temp := Make_Temporary (Loc, 'R', Prio);
                Append_To (L,
                   Make_Object_Declaration (Loc,
                      Defining_Identifier => Temp,
@@ -11219,15 +12790,15 @@ package body Exp_Ch9 is
                        New_Occurrence_Of (RTE (RE_Any_Priority), Loc),
                      Expression          => Relocate_Node (Prio)));
 
-                  Append_To (Args, New_Occurrence_Of (Temp, Loc));
+               Append_To (Args, New_Occurrence_Of (Temp, Loc));
             end if;
          end;
 
       --  When no priority is specified but an xx_Handler pragma is, we default
       --  to System.Interrupts.Default_Interrupt_Priority, see D.3(10).
 
-      elsif Has_Interrupt_Handler (Ptyp)
-        or else Has_Attach_Handler (Ptyp)
+      elsif Has_Attach_Handler (Ptyp)
+        or else Has_Interrupt_Handler (Ptyp)
       then
          Append_To (Args,
            New_Reference_To (RTE (RE_Default_Interrupt_Priority), Loc));
@@ -11244,13 +12815,19 @@ package body Exp_Ch9 is
       --  is a pointer to the record generated by the compiler to represent
       --  the protected object.
 
+      --  A protected type without entries that covers an interface and
+      --  overrides the abstract routines with protected procedures is
+      --  considered equivalent to a protected type with entries in the
+      --  context of dispatching select statements.
+
       if Has_Entry
-        or else Has_Interrupt_Handler (Ptyp)
-        or else Has_Attach_Handler (Ptyp)
-        or else Has_Abstract_Interfaces (Protect_Rec)
+        or else Has_Interfaces (Protect_Rec)
+        or else
+          ((Has_Attach_Handler (Ptyp) or else Has_Interrupt_Handler (Ptyp))
+             and then not Restriction_Active (No_Dynamic_Attachment))
       then
          declare
-            Pkg_Id : constant RTU_Id := Corresponding_Runtime_Package (Ptyp);
+            Pkg_Id : constant RTU_Id  := Corresponding_Runtime_Package (Ptyp);
 
             Called_Subp : RE_Id;
 
@@ -11269,10 +12846,13 @@ package body Exp_Ch9 is
                   raise Program_Error;
             end case;
 
-            if Has_Entry or else not Restricted then
+            if Has_Entry
+              or else not Restricted
+              or else Has_Interfaces (Protect_Rec)
+            then
                Append_To (Args,
                  Make_Attribute_Reference (Loc,
-                   Prefix => Make_Identifier (Loc, Name_uInit),
+                   Prefix         => Make_Identifier (Loc, Name_uInit),
                    Attribute_Name => Name_Address));
             end if;
 
@@ -11299,9 +12879,22 @@ package body Exp_Ch9 is
 
                   Append_To (Args,
                     Make_Attribute_Reference (Loc,
-                      Prefix =>
-                        New_Reference_To (P_Arr, Loc),
+                      Prefix         => New_Reference_To (P_Arr, Loc),
                       Attribute_Name => Name_Unrestricted_Access));
+
+                  --  Build_Entry_Names generation flag. When set to true, the
+                  --  runtime will allocate an array to hold the string names
+                  --  of protected entries.
+
+                  if not Restricted_Profile then
+                     if Entry_Names_OK then
+                        Append_To (Args,
+                          New_Reference_To (Standard_True, Loc));
+                     else
+                        Append_To (Args,
+                          New_Reference_To (Standard_False, Loc));
+                     end if;
+                  end if;
                end if;
 
             elsif Pkg_Id = System_Tasking_Protected_Objects_Single_Entry then
@@ -11310,6 +12903,7 @@ package body Exp_Ch9 is
             elsif Pkg_Id = System_Tasking_Protected_Objects_Entries then
                Append_To (Args, Make_Null (Loc));
                Append_To (Args, Make_Null (Loc));
+               Append_To (Args, New_Reference_To (Standard_False, Loc));
             end if;
 
             Append_To (L,
@@ -11399,7 +12993,7 @@ package body Exp_Ch9 is
                  Make_Attribute_Reference (Loc,
                    Prefix =>
                      Make_Selected_Component (Loc,
-                       Prefix => Make_Identifier (Loc, Name_uInit),
+                       Prefix        => Make_Identifier (Loc, Name_uInit),
                        Selector_Name => Make_Identifier (Loc, Name_uObject)),
                    Attribute_Name => Name_Unchecked_Access));
 
@@ -11422,13 +13016,13 @@ package body Exp_Ch9 is
 
    function Make_Task_Create_Call (Task_Rec : Entity_Id) return Node_Id is
       Loc    : constant Source_Ptr := Sloc (Task_Rec);
+      Args   : List_Id;
+      Ecount : Node_Id;
       Name   : Node_Id;
-      Tdef   : Node_Id;
       Tdec   : Node_Id;
-      Ttyp   : Node_Id;
+      Tdef   : Node_Id;
       Tnam   : Name_Id;
-      Args   : List_Id;
-      Ecount : Node_Id;
+      Ttyp   : Node_Id;
 
    begin
       Ttyp := Corresponding_Concurrent_Type (Task_Rec);
@@ -11463,10 +13057,10 @@ package body Exp_Ch9 is
       --  Priority parameter. Set to Unspecified_Priority unless there is a
       --  priority pragma, in which case we take the value from the pragma.
 
-      if Present (Tdef) and then Has_Priority_Pragma (Tdef) then
+      if Present (Tdef) and then Has_Pragma_Priority (Tdef) then
          Append_To (Args,
            Make_Selected_Component (Loc,
-             Prefix => Make_Identifier (Loc, Name_uInit),
+             Prefix        => Make_Identifier (Loc, Name_uInit),
              Selector_Name => Make_Identifier (Loc, Name_uPriority)));
       else
          Append_To (Args,
@@ -11483,10 +13077,10 @@ package body Exp_Ch9 is
          if Preallocated_Stacks_On_Target then
             Append_To (Args,
               Make_Attribute_Reference (Loc,
-                Prefix         => Make_Selected_Component (Loc,
-                  Prefix        => Make_Identifier (Loc, Name_uInit),
-                  Selector_Name =>
-                    Make_Identifier (Loc, Name_uStack)),
+                Prefix         =>
+                  Make_Selected_Component (Loc,
+                    Prefix        => Make_Identifier (Loc, Name_uInit),
+                    Selector_Name => Make_Identifier (Loc, Name_uStack)),
                 Attribute_Name => Name_Address));
 
          else
@@ -11507,7 +13101,7 @@ package body Exp_Ch9 is
       then
          Append_To (Args,
            Make_Selected_Component (Loc,
-             Prefix => Make_Identifier (Loc, Name_uInit),
+             Prefix        => Make_Identifier (Loc, Name_uInit),
              Selector_Name => Make_Identifier (Loc, Name_uSize)));
 
       else
@@ -11523,7 +13117,7 @@ package body Exp_Ch9 is
       then
          Append_To (Args,
            Make_Selected_Component (Loc,
-             Prefix => Make_Identifier (Loc, Name_uInit),
+             Prefix        => Make_Identifier (Loc, Name_uInit),
              Selector_Name => Make_Identifier (Loc, Name_uTask_Info)));
 
       else
@@ -11531,6 +13125,23 @@ package body Exp_Ch9 is
            New_Reference_To (RTE (RE_Unspecified_Task_Info), Loc));
       end if;
 
+      --  CPU parameter. Set to Unspecified_CPU unless there is a CPU pragma,
+      --  in which case we take the value from the pragma. The parameter is
+      --  passed as an Integer because in the case of unspecified CPU the
+      --  value is not in the range of CPU_Range.
+
+      if Present (Tdef) and then Has_Pragma_CPU (Tdef) then
+         Append_To (Args,
+           Convert_To (Standard_Integer,
+             Make_Selected_Component (Loc,
+               Prefix        => Make_Identifier (Loc, Name_uInit),
+               Selector_Name => Make_Identifier (Loc, Name_uCPU))));
+
+      else
+         Append_To (Args,
+           New_Reference_To (RTE (RE_Unspecified_CPU), Loc));
+      end if;
+
       if not Restricted_Profile then
 
          --  Deadline parameter. If no Relative_Deadline pragma is present,
@@ -11545,7 +13156,8 @@ package body Exp_Ch9 is
          if Present (Tdef) and then Has_Relative_Deadline_Pragma (Tdef) then
             Append_To (Args,
               Make_Selected_Component (Loc,
-                Prefix => Make_Identifier (Loc, Name_uInit),
+                Prefix        =>
+                  Make_Identifier (Loc, Name_uInit),
                 Selector_Name =>
                   Make_Identifier (Loc, Name_uRelative_Deadline)));
 
@@ -11556,6 +13168,31 @@ package body Exp_Ch9 is
               New_Reference_To (RTE (RE_Time_Span_Zero), Loc));
          end if;
 
+         --  Dispatching_Domain parameter. If no Dispatching_Domain pragma or
+         --  aspect is present, then the dispatching domain is null. If a
+         --  pragma or aspect is present, then the dispatching domain is taken
+         --  from the _Dispatching_Domain field of the task value record,
+         --  which was set from the pragma value. Note that this parameter
+         --  must not be generated for the restricted profiles since Ravenscar
+         --  does not allow dispatching domains.
+
+         --  Case where pragma or aspect Dispatching_Domain applies: use given
+         --  value.
+
+         if Present (Tdef) and then Has_Pragma_Dispatching_Domain (Tdef) then
+            Append_To (Args,
+              Make_Selected_Component (Loc,
+                Prefix        =>
+                  Make_Identifier (Loc, Name_uInit),
+                Selector_Name =>
+                  Make_Identifier (Loc, Name_uDispatching_Domain)));
+
+         --  No pragma or aspect Dispatching_Domain apply to the task
+
+         else
+            Append_To (Args, Make_Null (Loc));
+         end if;
+
          --  Number of entries. This is an expression of the form:
 
          --    n + _Init.a'Length + _Init.a'B'Length + ...
@@ -11574,14 +13211,14 @@ package body Exp_Ch9 is
 
          --  Master parameter. This is a reference to the _Master parameter of
          --  the initialization procedure, except in the case of the pragma
-         --  Restrictions (No_Task_Hierarchy) where the value is fixed to 3.
-         --  See comments in System.Tasking.Initialization.Init_RTS for the
-         --  value 3.
+         --  Restrictions (No_Task_Hierarchy) where the value is fixed to
+         --  System.Tasking.Library_Task_Level.
 
          if Restriction_Active (No_Task_Hierarchy) = False then
             Append_To (Args, Make_Identifier (Loc, Name_uMaster));
          else
-            Append_To (Args, Make_Integer_Literal (Loc, 3));
+            Append_To (Args,
+              New_Occurrence_Of (RTE (RE_Library_Task_Level), Loc));
          end if;
       end if;
 
@@ -11663,12 +13300,15 @@ package body Exp_Ch9 is
       if Present (Tdef)
         and then Has_Task_Name_Pragma (Tdef)
       then
+         --  Copy expression in full, because it may be dynamic and have
+         --  side effects.
+
          Append_To (Args,
-           New_Copy (
-             Expression (First (
-               Pragma_Argument_Associations (
-                 Find_Task_Or_Protected_Pragma
-                   (Tdef, Name_Task_Name))))));
+           New_Copy_Tree
+             (Expression (First
+                           (Pragma_Argument_Associations
+                             (Find_Task_Or_Protected_Pragma
+                               (Tdef, Name_Task_Name))))));
 
       else
          Append_To (Args, Make_Identifier (Loc, Name_uTask_Name));
@@ -11679,17 +13319,32 @@ package body Exp_Ch9 is
 
       Append_To (Args,
         Make_Selected_Component (Loc,
-          Prefix => Make_Identifier (Loc, Name_uInit),
+          Prefix        => Make_Identifier (Loc, Name_uInit),
           Selector_Name => Make_Identifier (Loc, Name_uTask_Id)));
 
+      --  Build_Entry_Names generation flag. When set to true, the runtime
+      --  will allocate an array to hold the string names of task entries.
+
+      if not Restricted_Profile then
+         if Has_Entries (Ttyp)
+           and then Entry_Names_OK
+         then
+            Append_To (Args, New_Reference_To (Standard_True, Loc));
+         else
+            Append_To (Args, New_Reference_To (Standard_False, Loc));
+         end if;
+      end if;
+
       if Restricted_Profile then
          Name := New_Reference_To (RTE (RE_Create_Restricted_Task), Loc);
       else
          Name := New_Reference_To (RTE (RE_Create_Task), Loc);
       end if;
 
-      return Make_Procedure_Call_Statement (Loc,
-        Name => Name, Parameter_Associations => Args);
+      return
+        Make_Procedure_Call_Statement (Loc,
+          Name => Name,
+          Parameter_Associations => Args);
    end Make_Task_Create_Call;
 
    ------------------------------
@@ -11766,8 +13421,7 @@ package body Exp_Ch9 is
             --  Generate:
             --    Jnn : aliased <formal-type>
 
-            Temp_Nam :=
-              Make_Defining_Identifier (Loc, New_Internal_Name ('J'));
+            Temp_Nam := Make_Temporary (Loc, 'J');
 
             Append_To (Decls,
               Make_Object_Declaration (Loc,
@@ -11833,7 +13487,7 @@ package body Exp_Ch9 is
       --      <actual2>'reference;
       --      ...);
 
-      P := Make_Defining_Identifier (Loc, New_Internal_Name ('P'));
+      P := Make_Temporary (Loc, 'P');
 
       Append_To (Decls,
         Make_Object_Declaration (Loc,
@@ -11880,7 +13534,7 @@ package body Exp_Ch9 is
                 Expression =>
                   Make_Explicit_Dereference (Loc,
                     Make_Selected_Component (Loc,
-                      Prefix =>
+                      Prefix        =>
                         New_Reference_To (P, Loc),
                       Selector_Name =>
                         Make_Identifier (Loc, Chars (Formal)))));
@@ -11952,7 +13606,7 @@ package body Exp_Ch9 is
          when ' ' =>
             return True;
 
-         --  FIFO_Within_Priorities certainly certainly does not permit this
+         --  FIFO_Within_Priorities certainly does not permit this
          --  optimization since the Rendezvous is a scheduling action that may
          --  require some other task to be run.