OSDN Git Service

2010-12-06 Jerry DeLisle <jvdelisle@gcc.gnu.org>
[pf3gnuchains/gcc-fork.git] / gcc / ada / sem_cat.adb
index e790e55..9311beb 100644 (file)
@@ -6,7 +6,7 @@
 --                                                                          --
 --                                 B o d y                                  --
 --                                                                          --
---          Copyright (C) 1992-2008, Free Software Foundation, Inc.         --
+--          Copyright (C) 1992-2010, 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- --
@@ -28,13 +28,14 @@ with Debug;    use Debug;
 with Einfo;    use Einfo;
 with Elists;   use Elists;
 with Errout;   use Errout;
-with Exp_Util; use Exp_Util;
+with Exp_Disp; use Exp_Disp;
 with Fname;    use Fname;
 with Lib;      use Lib;
 with Namet;    use Namet;
 with Nlists;   use Nlists;
 with Opt;      use Opt;
 with Sem;      use Sem;
+with Sem_Aux;  use Sem_Aux;
 with Sem_Eval; use Sem_Eval;
 with Sem_Util; use Sem_Util;
 with Sinfo;    use Sinfo;
@@ -76,13 +77,13 @@ package body Sem_Cat is
    --  at any place.
 
    function In_RCI_Declaration (N : Node_Id) return Boolean;
-   --  Determines if a declaration is  within the visible part of  a Remote
-   --  Call Interface compilation unit, for semantic checking purposes only,
+   --  Determines if a declaration is  within the visible part of a Remote
+   --  Call Interface compilation unit, for semantic checking purposes only
    --  (returns false within an instance and within the package body).
 
    function In_RT_Declaration return Boolean;
-   --  Determines if current scope is within a Remote Types compilation unit,
-   --  for semantic checking purposes.
+   --  Determines if current scope is within the declaration of a Remote Types
+   --  unit, for semantic checking purposes.
 
    function Is_Non_Remote_Access_Type (E : Entity_Id) return Boolean;
    --  Returns true if the entity is a type whose full view is a non-remote
@@ -98,15 +99,10 @@ package body Sem_Cat is
 
    procedure Validate_Remote_Access_Object_Type_Declaration (T : Entity_Id);
    --  Check validity of declaration if RCI or RT unit. It should not contain
-   --  the declaration of an access-to-object type unless it is a
-   --  general access type that designates a class-wide limited
-   --  private type. There are also constraints about the primitive
-   --  subprograms of the class-wide type. RM E.2 (9, 13, 14)
-
-   function Is_Recursively_Limited_Private (E : Entity_Id) return Boolean;
-   --  Return True if E is a limited private type, or if E is a private
-   --  extension of a type whose parent verifies this property (hence the
-   --  recursive keyword).
+   --  the declaration of an access-to-object type unless it is a general
+   --  access type that designates a class-wide limited private type. There are
+   --  also constraints about the primitive subprograms of the class-wide type.
+   --  RM E.2 (9, 13, 14)
 
    ---------------------------------------
    -- Check_Categorization_Dependencies --
@@ -118,22 +114,18 @@ package body Sem_Cat is
       Info_Node       : Node_Id;
       Is_Subunit      : Boolean)
    is
-      N : constant Node_Id := Info_Node;
+      N   : constant Node_Id := Info_Node;
+      Err : Boolean;
 
       --  Here we define an enumeration type to represent categorization types,
       --  ordered so that a unit with a given categorization can only WITH
       --  units with lower or equal categorization type.
 
-      --  Note that we take advantage of E.2(14) to define a category
-      --  Preelaborated and treat pragma Preelaborate as a categorization
-      --  pragma that defines that category.
-
       type Categorization is
         (Pure,
          Shared_Passive,
          Remote_Types,
          Remote_Call_Interface,
-         Preelaborated,
          Normal);
 
       function Get_Categorization (E : Entity_Id) return Categorization;
@@ -151,7 +143,7 @@ package body Sem_Cat is
          --  to apply to the same library unit, in which case the unit has
          --  all associated categories, so we need to be careful here to
          --  check pragmas in proper Categorization order in order to
-         --  return the lowest appplicable value.
+         --  return the lowest applicable value.
 
          --  Ignore Pure specification if set by pragma Pure_Function
 
@@ -170,9 +162,6 @@ package body Sem_Cat is
          elsif Is_Remote_Call_Interface (E) then
             return Remote_Call_Interface;
 
-         elsif Is_Preelaborated (E) then
-            return Preelaborated;
-
          else
             return Normal;
          end if;
@@ -191,20 +180,26 @@ package body Sem_Cat is
          return;
       end if;
 
-      Unit_Category := Get_Categorization (Unit_Entity);
-      With_Category := Get_Categorization (Depended_Entity);
+      --  First check 10.2.1 (11/1) rules on preelaborate packages
 
-      --  These messages are wanings in GNAT mode, to allow it to be
-      --  judiciously turned off. Otherwise it is a real error.
+      if Is_Preelaborated (Unit_Entity)
+        and then not Is_Preelaborated (Depended_Entity)
+        and then not Is_Pure (Depended_Entity)
+      then
+         Err := True;
+      else
+         Err := False;
+      end if;
 
-      Error_Msg_Warn := GNAT_Mode;
+      --  Check categorization rules of RM E.2(5)
 
-      --  Check for possible error
+      Unit_Category := Get_Categorization (Unit_Entity);
+      With_Category := Get_Categorization (Depended_Entity);
 
       if With_Category > Unit_Category then
 
          --  Special case: Remote_Types and Remote_Call_Interface are allowed
-         --  to be with'ed in package body.
+         --  to WITH anything in the package body, per (RM E.2(5)).
 
          if (Unit_Category = Remote_Types
                or else Unit_Category = Remote_Call_Interface)
@@ -212,52 +207,80 @@ package body Sem_Cat is
          then
             null;
 
-         --  Here we have an error
+         --  Special case: Remote_Types can depend on Preelaborated per
+         --  Ada 2005 AI 0206.
+
+         elsif Unit_Category = Remote_Types
+           and then Is_Preelaborated (Depended_Entity)
+         then
+            null;
+
+         --  All other cases, we do have an error
 
          else
-            --  Don't give error if main unit is not an internal unit, and the
-            --  unit generating the message is an internal unit. This is the
-            --  situation in which such messages would be ignored in any case,
-            --  so it is convenient not to generate them (since it causes
-            --  annoying interference with debugging).
-
-            if Is_Internal_File_Name (Unit_File_Name (Current_Sem_Unit))
-              and then not Is_Internal_File_Name (Unit_File_Name (Main_Unit))
-            then
-               return;
+            Err := True;
+         end if;
+      end if;
 
-            --  Subunit case
+      --  Here if we have an error
 
-            elsif Is_Subunit then
-               Error_Msg_NE
-                 ("<subunit cannot depend on& " &
-                  "(parent has wrong categorization)", N, Depended_Entity);
+      if Err then
 
-            --  Normal unit, not subunit
+         --  These messages are warnings in GNAT mode or if the -gnateP switch
+         --  was set. Otherwise these are real errors for real illegalities.
 
-            else
-               Error_Msg_NE
-                 ("<cannot depend on& " &
-                  "(wrong categorization)", N, Depended_Entity);
-            end if;
+         --  The reason we suppress these errors in GNAT mode is that the run-
+         --  time has several instances of violations of the categorization
+         --  errors (e.g. Pure units withing Preelaborate units. All these
+         --  violations are harmless in the cases where we intend them, and
+         --  we suppress the warnings with Warnings (Off). In cases where we
+         --  do not intend the violation, warnings are errors in GNAT mode
+         --  anyway, so we will still get an error.
 
-            --  Add further explanation for common cases
+         Error_Msg_Warn :=
+           Treat_Categorization_Errors_As_Warnings or GNAT_Mode;
 
-            case Unit_Category is
-               when Pure =>
-                  Error_Msg_NE
-                    ("\<pure unit cannot depend on non-pure unit",
-                    N, Depended_Entity);
+         --  Don't give error if main unit is not an internal unit, and the
+         --  unit generating the message is an internal unit. This is the
+         --  situation in which such messages would be ignored in any case,
+         --  so it is convenient not to generate them (since it causes
+         --  annoying interference with debugging).
 
-               when Preelaborated =>
-                  Error_Msg_NE
-                    ("\<preelaborated unit cannot depend on " &
-                     "non-preelaborated unit",
-                     N, Depended_Entity);
+         if Is_Internal_File_Name (Unit_File_Name (Current_Sem_Unit))
+           and then not Is_Internal_File_Name (Unit_File_Name (Main_Unit))
+         then
+            return;
 
-               when others =>
-                  null;
-            end case;
+         --  Subunit case
+
+         elsif Is_Subunit then
+            Error_Msg_NE
+              ("<subunit cannot depend on& " &
+               "(parent has wrong categorization)", N, Depended_Entity);
+
+         --  Normal unit, not subunit
+
+         else
+            Error_Msg_NE
+              ("<cannot depend on& " &
+               "(wrong categorization)", N, Depended_Entity);
+         end if;
+
+         --  Add further explanation for Pure/Preelaborate common cases
+
+         if Unit_Category = Pure then
+            Error_Msg_NE
+              ("\<pure unit cannot depend on non-pure unit",
+               N, Depended_Entity);
+
+         elsif Is_Preelaborated (Unit_Entity)
+           and then not Is_Preelaborated (Depended_Entity)
+           and then not Is_Pure (Depended_Entity)
+         then
+            Error_Msg_NE
+              ("\<preelaborated unit cannot depend on "
+               & "non-preelaborated unit",
+               N, Depended_Entity);
          end if;
       end if;
    end Check_Categorization_Dependencies;
@@ -384,7 +407,7 @@ package body Sem_Cat is
       --  currently visible.
 
       return Present (Rep_Item)
-        and then (Ada_Version < Ada_05
+        and then (Ada_Version < Ada_2005
                    or else At_Any_Place
                    or else not Is_Hidden (Entity (Rep_Item)));
    end Has_Stream_Attribute_Definition;
@@ -438,14 +461,16 @@ package body Sem_Cat is
       --  of an RCI unit.
 
       return Is_Remote_Call_Interface (Unit_Entity)
-        and then (Ekind (Unit_Entity) = E_Package
-                  or else Ekind (Unit_Entity) = E_Generic_Package)
+        and then Is_Package_Or_Generic_Package (Unit_Entity)
         and then Unit_Kind /= N_Package_Body
         and then List_Containing (N) =
                   Visible_Declarations
                     (Specification (Unit_Declaration_Node (Unit_Entity)))
         and then not In_Package_Body (Unit_Entity)
         and then not In_Instance;
+
+      --  What about the case of a nested package in the visible part???
+      --  This case is missed by the List_Containing check above???
    end In_RCI_Declaration;
 
    -----------------------
@@ -461,8 +486,7 @@ package body Sem_Cat is
       --  There are no restrictions on the body of a Remote Types unit
 
       return Is_Remote_Types (Unit_Entity)
-        and then (Ekind (Unit_Entity) = E_Package
-                   or else Ekind (Unit_Entity) = E_Generic_Package)
+        and then Is_Package_Or_Generic_Package (Unit_Entity)
         and then Unit_Kind /= N_Package_Body
         and then not In_Package_Body (Unit_Entity)
         and then not In_Instance;
@@ -531,47 +555,6 @@ package body Sem_Cat is
         and then not Is_Remote_Access_To_Subprogram_Type (U_E);
    end Is_Non_Remote_Access_Type;
 
-   ------------------------------------
-   -- Is_Recursively_Limited_Private --
-   ------------------------------------
-
-   function Is_Recursively_Limited_Private (E : Entity_Id) return Boolean is
-      P : constant Node_Id := Parent (E);
-
-   begin
-      if Nkind (P) = N_Private_Type_Declaration
-        and then Is_Limited_Record (E)
-      then
-         return True;
-
-      --  A limited interface is not currently a legal ancestor for the
-      --  designated type of an RACW type, because a type that implements
-      --  such an interface need not be limited. However, the ARG seems to
-      --  incline towards allowing an access to classwide limited interface
-      --  type as a remote access type. This may be revised when the ARG
-      --  rules on this question, but it seems safe to allow it for now,
-      --  in order to see whether it is a useful extension for distributed
-      --  programming, in particular for Brad Moore's buffer taxonomy.
-
-      elsif Is_Limited_Record (E)
-        and then Is_Limited_Interface (E)
-      then
-         return True;
-
-      elsif Nkind (P) = N_Private_Extension_Declaration then
-         return Is_Recursively_Limited_Private (Etype (E));
-
-      elsif Nkind (P) = N_Formal_Type_Declaration
-        and then Ekind (E) = E_Record_Type_With_Private
-        and then Is_Generic_Type (E)
-        and then Is_Limited_Record (E)
-      then
-         return True;
-      else
-         return False;
-      end if;
-   end Is_Recursively_Limited_Private;
-
    ----------------------------------
    -- Missing_Read_Write_Attribute --
    ----------------------------------
@@ -755,14 +738,17 @@ package body Sem_Cat is
          end if;
       end if;
 
-      Set_Is_Remote_Types (E, Is_Remote_Types (Scop));
+      Set_Is_Remote_Types
+        (E, Is_Remote_Types (Scop)
+              and then not (In_Private_Part (Scop)
+                              or else In_Package_Body (Scop)));
    end Set_Categorization_From_Scope;
 
    ------------------------------
    -- Static_Discriminant_Expr --
    ------------------------------
 
-   --  We need to accomodate a Why_Not_Static call somehow here ???
+   --  We need to accommodate a Why_Not_Static call somehow here ???
 
    function Static_Discriminant_Expr (L : List_Id) return Boolean is
       Discriminant_Spec : Node_Id;
@@ -802,7 +788,7 @@ package body Sem_Cat is
 
             --  This test is skipped in Ada 2005 (see AI-366)
 
-            if Ada_Version < Ada_05
+            if Ada_Version < Ada_2005
               and then Comes_From_Source (T)
               and then In_Pure_Unit
               and then not In_Subprogram_Task_Protected_Unit
@@ -963,7 +949,7 @@ package body Sem_Cat is
       end;
 
       --  Child depends on parent; therefore parent should also be categorized
-      --  and satify the dependency hierarchy.
+      --  and satisfy the dependency hierarchy.
 
       --  Check if N is a child spec
 
@@ -999,7 +985,7 @@ package body Sem_Cat is
       --  Don't need this check in Ada 2005 mode, where this is all taken
       --  care of by the mechanism for Preelaborable Initialization.
 
-      if Ada_Version >= Ada_05 then
+      if Ada_Version >= Ada_2005 then
          return;
       end if;
 
@@ -1095,28 +1081,25 @@ package body Sem_Cat is
       --  Exclude generic specs from the checks (this will get rechecked
       --  on instantiations).
 
-      if Inside_A_Generic
-        and then No (Enclosing_Generic_Body (Id))
-      then
+      if Inside_A_Generic and then No (Enclosing_Generic_Body (Id)) then
          return;
       end if;
 
-      --  Required checks for declaration that is in a preelaborated
-      --  package and is not within some subprogram.
+      --  Required checks for declaration that is in a preelaborated package
+      --  and is not within some subprogram.
 
       if In_Preelaborated_Unit
         and then not In_Subprogram_Or_Concurrent_Unit
       then
          --  Check for default initialized variable case. Note that in
-         --  accordance with (RM B.1(24)) imported objects are not
-         --  subject to default initialization.
+         --  accordance with (RM B.1(24)) imported objects are not subject to
+         --  default initialization.
          --  If the initialization does not come from source and is an
          --  aggregate, it is a static initialization that replaces an
          --  implicit call, and must be treated as such.
 
          if Present (E)
-           and then
-            (Comes_From_Source (E) or else Nkind (E) /= N_Aggregate)
+           and then (Comes_From_Source (E) or else Nkind (E) /= N_Aggregate)
          then
             null;
 
@@ -1183,7 +1166,7 @@ package body Sem_Cat is
                      --  marked with this pragma in the predefined library are
                      --  not treated specially.
 
-                     if Ada_Version < Ada_05 then
+                     if Ada_Version < Ada_2005 then
                         Error_Msg_N
                           ("private object not allowed in preelaborated unit",
                            N);
@@ -1216,7 +1199,7 @@ package body Sem_Cat is
                         then
                            Error_Msg_Sloc := Sloc (Ent);
 
-                           if Ada_Version >= Ada_05 then
+                           if Ada_Version >= Ada_2005 then
                               Error_Msg_NE
                                 ("\would be legal if pragma Preelaborable_" &
                                  "Initialization given for & #", N, Ent);
@@ -1244,13 +1227,8 @@ package body Sem_Cat is
                elsif Nkind (Odf) = N_Subtype_Indication then
                   Ent := Etype (Subtype_Mark (Odf));
 
-               elsif
-                  Nkind (Odf) = N_Constrained_Array_Definition
-               then
+               elsif Nkind (Odf) = N_Constrained_Array_Definition then
                   Ent := Component_Type (T);
-
-               --  else
-               --     return;
                end if;
 
                if Is_Task_Type (Ent)
@@ -1264,9 +1242,9 @@ package body Sem_Cat is
             end;
          end if;
 
-         --  Non-static discriminant not allowed in preelaborated unit
-         --  Controlled object of a type with a user-defined Initialize
-         --  is forbidden as well.
+         --  Non-static discriminants not allowed in preelaborated unit.
+         --  Objects of a controlled type with a user-defined Initialize
+         --  are forbidden as well.
 
          if Is_Record_Type (Etype (Id)) then
             declare
@@ -1282,7 +1260,7 @@ package body Sem_Cat is
 
                   if Nkind (PEE) = N_Full_Type_Declaration
                     and then not Static_Discriminant_Expr
-                                  (Discriminant_Specifications (PEE))
+                                   (Discriminant_Specifications (PEE))
                   then
                      Error_Msg_N
                        ("non-static discriminant in preelaborated unit",
@@ -1304,23 +1282,21 @@ package body Sem_Cat is
       --  except within a subprogram, generic subprogram, task unit, or
       --  protected unit (RM 10.2.1(16)).
 
-      if In_Pure_Unit
-        and then not In_Subprogram_Task_Protected_Unit
-      then
+      if In_Pure_Unit and then not In_Subprogram_Task_Protected_Unit then
          Error_Msg_N ("declaration of variable not allowed in pure unit", N);
 
       --  The visible part of an RCI library unit must not contain the
       --  declaration of a variable (RM E.1.3(9))
 
       elsif In_RCI_Declaration (N) then
-         Error_Msg_N ("declaration of variable not allowed in rci unit", N);
+         Error_Msg_N ("visible variable not allowed in 'R'C'I unit", N);
 
       --  The visible part of a Shared Passive library unit must not contain
       --  the declaration of a variable (RM E.2.2(7))
 
-      elsif In_RT_Declaration then
+      elsif In_RT_Declaration and then not In_Private_Part (Id) then
          Error_Msg_N
-           ("variable declaration not allowed in remote types unit", N);
+           ("visible variable not allowed in remote types unit", N);
       end if;
 
    end Validate_Object_Declaration;
@@ -1367,6 +1343,12 @@ package body Sem_Cat is
    begin
       Desig_Type := Etype (Designated_Type (T));
 
+      --  No action needed for concurrent types
+
+      if Is_Concurrent_Type (Desig_Type) then
+         return;
+      end if;
+
       Primitive_Subprograms := Primitive_Operations (Desig_Type);
 
       Subprogram_Elmt := First_Elmt (Primitive_Subprograms);
@@ -1399,6 +1381,18 @@ package body Sem_Cat is
                     ("limited return type must have Read and Write attributes",
                      Parent (Subprogram));
                   Explain_Limited_Type (Rtyp, Parent (Subprogram));
+
+               --  Check that the return type supports external streaming.
+               --  Note that the language of the standard (E.2.2(14)) does not
+               --  explicitly mention that case, but it really does not make
+               --  sense to return a value containing a local access type.
+
+               elsif Missing_Read_Write_Attributes (Rtyp)
+                       and then not Error_Posted (Rtyp)
+               then
+                  Illegal_RACW ("return type containing non-remote access "
+                    & "must have Read and Write attributes",
+                    Parent (Subprogram));
                end if;
 
             end if;
@@ -1419,11 +1413,12 @@ package body Sem_Cat is
 
                null;
 
-            elsif Ekind (Param_Type) = E_Anonymous_Access_Type
-              or else Ekind (Param_Type) = E_Anonymous_Access_Subprogram_Type
+            elsif Ekind_In (Param_Type, E_Anonymous_Access_Type,
+                                        E_Anonymous_Access_Subprogram_Type)
             then
-               --  From RM E.2.2(14), no access parameter other than
-               --  controlling ones may be used.
+               --  From RM E.2.2(14), no anonymous access parameter other than
+               --  controlling ones may be used (because an anonymous access
+               --  type never supports external streaming).
 
                Illegal_RACW ("non-controlling access parameter", Param_Spec);
 
@@ -1441,6 +1436,12 @@ package body Sem_Cat is
                      Param_Spec);
                   Explain_Limited_Type (Param_Type, Param_Spec);
                end if;
+
+            elsif Missing_Read_Write_Attributes (Param_Type)
+               and then not Error_Posted (Param_Type)
+            then
+               Illegal_RACW ("parameter containing non-remote access "
+                 & "must have Read and Write attributes", Param_Spec);
             end if;
 
             --  Check next parameter in this subprogram
@@ -1469,9 +1470,9 @@ package body Sem_Cat is
                  ("limited type not allowed in rci unit", Parent (E));
                Explain_Limited_Type (E, Parent (E));
 
-            elsif Ekind (E) = E_Generic_Function
-              or else Ekind (E) = E_Generic_Package
-              or else Ekind (E) = E_Generic_Procedure
+            elsif Ekind_In (E, E_Generic_Function,
+                               E_Generic_Package,
+                               E_Generic_Procedure)
             then
                Error_Msg_N ("generic declaration not allowed in rci unit",
                  Parent (E));
@@ -1522,12 +1523,14 @@ package body Sem_Cat is
       Error_Node      : Node_Id := N;
 
    begin
-      --  There are two possible cases in which this procedure is called:
+      --  This procedure enforces rules on subprogram and access to subprogram
+      --  declarations in RCI units. These rules do not apply to expander
+      --  generated routines, which are not remote subprograms. It is called:
 
-      --    1. called from Analyze_Subprogram_Declaration.
-      --    2. called from Validate_Object_Declaration (access to subprogram).
+      --    1. from Analyze_Subprogram_Declaration.
+      --    2. from Validate_Object_Declaration (access to subprogram).
 
-      if not In_RCI_Declaration (N) then
+      if not (Comes_From_Source (N) and then In_RCI_Declaration (N)) then
          return;
       end if;
 
@@ -1535,6 +1538,11 @@ package body Sem_Cat is
          Profile := Parameter_Specifications (Specification (N));
 
       else pragma Assert (K = N_Object_Declaration);
+
+         --  The above assertion is dubious, the visible declarations of an
+         --  RCI unit never contain an object declaration, this should be an
+         --  ACCESS-to-object declaration???
+
          Id := Defining_Identifier (N);
 
          if Nkind (Id) = N_Defining_Identifier
@@ -1550,7 +1558,7 @@ package body Sem_Cat is
 
       --  Iterate through the parameter specification list, checking that
       --  no access parameter and no limited type parameter in the list.
-      --  RM E.2.3 (14)
+      --  RM E.2.3(14).
 
       if Present (Profile) then
          Param_Spec := First (Profile);
@@ -1559,7 +1567,6 @@ package body Sem_Cat is
             Type_Decl  := Parent (Param_Type);
 
             if Ekind (Param_Type) = E_Anonymous_Access_Type then
-
                if K = N_Subprogram_Declaration then
                   Error_Node := Param_Spec;
                end if;
@@ -1570,7 +1577,7 @@ package body Sem_Cat is
                  (Defining_Entity (Specification (N)))
                then
                   Error_Msg_N
-                    ("subprogram in rci unit cannot have access parameter",
+                    ("subprogram in 'R'C'I unit cannot have access parameter",
                       Error_Node);
                end if;
 
@@ -1617,7 +1624,7 @@ package body Sem_Cat is
                Base_Under_Type := Base_Type (Underlying_Type
                                               (Base_Param_Type));
 
-               if (Ada_Version < Ada_05
+               if (Ada_Version < Ada_2005
                      and then
                        (No (TSS (Base_Param_Type, TSS_Stream_Read))
                           or else
@@ -1627,7 +1634,7 @@ package body Sem_Cat is
                           or else
                         No (TSS (Base_Under_Type, TSS_Stream_Write))))
                  or else
-                   (Ada_Version >= Ada_05
+                   (Ada_Version >= Ada_2005
                       and then
                         (No (TSS (Base_Param_Type, TSS_Stream_Read))
                            or else
@@ -1647,23 +1654,50 @@ package body Sem_Cat is
                      Error_Node := Param_Spec;
                   end if;
 
-                  if Ada_Version >= Ada_05 then
+                  if Ada_Version >= Ada_2005 then
                      Error_Msg_N
-                       ("limited parameter in rci unit "
+                       ("limited parameter in 'R'C'I unit "
                           & "must have visible read/write attributes ",
                         Error_Node);
                   else
                      Error_Msg_N
-                       ("limited parameter in rci unit "
+                       ("limited parameter in 'R'C'I unit "
                           & "must have read/write attributes ",
                         Error_Node);
                   end if;
                   Explain_Limited_Type (Param_Type, Error_Node);
                end if;
-            end if;
 
+            --  In Ada 95, any non-remote access type (or any type with a
+            --  component of a non-remote access type) that is visible in an
+            --  RCI unit comes from a Remote_Types or Remote_Call_Interface
+            --  unit, and thus is already guaranteed to support external
+            --  streaming. However in Ada 2005 we have to account for the case
+            --  of named access types from declared pure units as well, which
+            --  may or may not support external streaming, and so we need to
+            --  perform a specific check for E.2.3(14/2) here.
+
+            --  Note that if the declaration of the type itself is illegal, we
+            --  do not perform this check since it might be a cascaded error.
+
+            else
+               if K = N_Subprogram_Declaration then
+                  Error_Node := Param_Spec;
+               end if;
+
+               if Missing_Read_Write_Attributes (Param_Type)
+                    and then not Error_Posted (Param_Type)
+               then
+                  Error_Msg_N
+                    ("parameter containing non-remote access in 'R'C'I "
+                     & "subprogram must have visible "
+                     & "Read and Write attributes", Error_Node);
+               end if;
+            end if;
             Next (Param_Spec);
          end loop;
+
+         --  No check on return type???
       end if;
    end Validate_RCI_Subprogram_Declaration;
 
@@ -1672,12 +1706,71 @@ package body Sem_Cat is
    ----------------------------------------------------
 
    procedure Validate_Remote_Access_Object_Type_Declaration (T : Entity_Id) is
+
+      function Is_Valid_Remote_Object_Type (E : Entity_Id) return Boolean;
+      --  True if tagged type E is a valid candidate as the root type of the
+      --  designated type for a RACW, i.e. a tagged limited private type, or a
+      --  limited interface type, or a private extension of such a type.
+
+      ---------------------------------
+      -- Is_Valid_Remote_Object_Type --
+      ---------------------------------
+
+      function Is_Valid_Remote_Object_Type (E : Entity_Id) return Boolean is
+         P : constant Node_Id := Parent (E);
+
+      begin
+         pragma Assert (Is_Tagged_Type (E));
+
+         --  Simple case: a limited private type
+
+         if Nkind (P) = N_Private_Type_Declaration
+           and then Is_Limited_Record (E)
+         then
+            return True;
+
+         --  A limited interface is not currently a legal ancestor for the
+         --  designated type of an RACW type, because a type that implements
+         --  such an interface need not be limited. However, the ARG seems to
+         --  incline towards allowing an access to classwide limited interface
+         --  type as a remote access type, as resolved in AI05-060. But note
+         --  that the expansion circuitry for RACWs that designate classwide
+         --  interfaces is not complete yet.
+
+         elsif Is_Limited_Record (E) and then Is_Limited_Interface (E) then
+            return True;
+
+         --  A generic tagged limited type is a valid candidate. Limitedness
+         --  will be checked again on the actual at instantiation point.
+
+         elsif Nkind (P) = N_Formal_Type_Declaration
+           and then Ekind (E) = E_Record_Type_With_Private
+           and then Is_Generic_Type (E)
+           and then Is_Limited_Record (E)
+         then
+            return True;
+
+         --  A private extension declaration is a valid candidate if its parent
+         --  type is.
+
+         elsif Nkind (P) = N_Private_Extension_Declaration then
+            return Is_Valid_Remote_Object_Type (Etype (E));
+
+         else
+            return False;
+         end if;
+      end Is_Valid_Remote_Object_Type;
+
+      --  Local variables
+
       Direct_Designated_Type : Entity_Id;
       Desig_Type             : Entity_Id;
 
+   --  Start of processing for Validate_Remote_Access_Object_Type_Declaration
+
    begin
-      --  We are called from Analyze_Type_Declaration, and the Nkind of the
-      --  given node is N_Access_To_Object_Definition.
+      --  We are called from Analyze_Full_Type_Declaration, and the Nkind of
+      --  the given node is N_Access_To_Object_Definition.
 
       if not Comes_From_Source (T)
         or else (not In_RCI_Declaration (Parent (T))
@@ -1696,12 +1789,12 @@ package body Sem_Cat is
 
       --  Check RCI or RT unit type declaration. It may not contain the
       --  declaration of an access-to-object type unless it is a general access
-      --  type that designates a class-wide limited private type. There are
-      --  also constraints on the primitive subprograms of the class-wide type
-      --  (RM E.2.2(14), see Validate_RACW_Primitives).
+      --  type that designates a class-wide limited private type or subtype.
+      --  There are also constraints on the primitive subprograms of the
+      --  class-wide type (RM E.2.2(14), see Validate_RACW_Primitives).
 
       if Ekind (T) /= E_General_Access_Type
-        or else Ekind (Designated_Type (T)) /= E_Class_Wide_Type
+        or else not Is_Class_Wide_Type (Designated_Type (T))
       then
          if In_RCI_Declaration (Parent (T)) then
             Error_Msg_N
@@ -1718,20 +1811,16 @@ package body Sem_Cat is
       Direct_Designated_Type := Designated_Type (T);
       Desig_Type := Etype (Direct_Designated_Type);
 
-      if not Is_Recursively_Limited_Private (Desig_Type) then
+      --  Why is the check below not in
+      --  Validate_Remote_Access_To_Class_Wide_Type???
+
+      if not Is_Valid_Remote_Object_Type (Desig_Type) then
          Error_Msg_N
            ("error in designated type of remote access to class-wide type", T);
          Error_Msg_N
            ("\must be tagged limited private or private extension", T);
          return;
       end if;
-
-      --  Now this is an RCI unit access-to-class-wide-limited-private type
-      --  declaration. Set the type entity to be Is_Remote_Call_Interface to
-      --  optimize later checks by avoiding tree traversal to find out if this
-      --  entity is inside an RCI unit.
-
-      Set_Is_Remote_Call_Interface (T);
    end Validate_Remote_Access_Object_Type_Declaration;
 
    -----------------------------------------------
@@ -1749,7 +1838,7 @@ package body Sem_Cat is
 
       --    Storage_Pool and Storage_Size are not defined for such types
       --
-      --    The expected type of allocator must not not be such a type.
+      --    The expected type of allocator must not be such a type.
 
       --    The actual parameter of generic instantiation must not be such a
       --    type if the formal parameter is of an access type.
@@ -1929,7 +2018,7 @@ package body Sem_Cat is
                      "non-remote access type", U_Typ);
                end if;
 
-               if Ada_Version >= Ada_05 then
+               if Ada_Version >= Ada_2005 then
                   Error_Msg_N
                     ("\must have visible Read and Write attribute " &
                      "definition clauses (RM E.2.2(8))", U_Typ);
@@ -1981,7 +2070,7 @@ package body Sem_Cat is
    --  Start of processing for Validate_SP_Access_Object_Type_Decl
 
    begin
-      --  We are called from Sem_Ch3.Analyze_Type_Declaration, and the
+      --  We are called from Sem_Ch3.Analyze_Full_Type_Declaration, and the
       --  Nkind of the given entity is N_Access_To_Object_Definition.
 
       if not Comes_From_Source (T)
@@ -2117,10 +2206,8 @@ package body Sem_Cat is
             Flag_Non_Static_Expr
               ("non-static object name in preelaborated unit", N);
 
-         --  We take the view that a constant defined in another preelaborated
-         --  unit is preelaborable, even though it may have a private type and
-         --  thus appear non-static in a client. This must be the intent of
-         --  the language, but currently is an RM gap ???
+         --  Give an error for a reference to a nonstatic constant, unless the
+         --  constant is in another GNAT library unit that is preelaborable.
 
          elsif Ekind (Entity (N)) = E_Constant
            and then not Is_Static_Expression (N)