]> gcc.gnu.org Git - gcc.git/blobdiff - gcc/ada/sem_cat.adb
ada: Fix detection of non-static expressions in records with pragmas
[gcc.git] / gcc / ada / sem_cat.adb
index e4615393dd2bfebcbd75bf619d5f873c5ab7cb5a..13dff3dbdd93989193a42e0104ca4a1a248a81c8 100644 (file)
@@ -6,7 +6,7 @@
 --                                                                          --
 --                                 B o d y                                  --
 --                                                                          --
---          Copyright (C) 1992-2012, Free Software Foundation, Inc.         --
+--          Copyright (C) 1992-2023, 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- --
 --                                                                          --
 ------------------------------------------------------------------------------
 
-with Atree;    use Atree;
-with Debug;    use Debug;
-with Einfo;    use Einfo;
-with Elists;   use Elists;
-with Errout;   use Errout;
-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_Attr; use Sem_Attr;
-with Sem_Aux;  use Sem_Aux;
-with Sem_Dist; use Sem_Dist;
-with Sem_Eval; use Sem_Eval;
-with Sem_Util; use Sem_Util;
-with Sinfo;    use Sinfo;
-with Snames;   use Snames;
-with Stand;    use Stand;
+with Atree;          use Atree;
+with Debug;          use Debug;
+with Einfo;          use Einfo;
+with Einfo.Entities; use Einfo.Entities;
+with Einfo.Utils;    use Einfo.Utils;
+with Elists;         use Elists;
+with Errout;         use Errout;
+with Lib;            use Lib;
+with Namet;          use Namet;
+with Nlists;         use Nlists;
+with Opt;            use Opt;
+with Sem;            use Sem;
+with Sem_Attr;       use Sem_Attr;
+with Sem_Aux;        use Sem_Aux;
+with Sem_Dist;       use Sem_Dist;
+with Sem_Eval;       use Sem_Eval;
+with Sem_Util;       use Sem_Util;
+with Sinfo;          use Sinfo;
+with Sinfo.Nodes;    use Sinfo.Nodes;
+with Sinfo.Utils;    use Sinfo.Utils;
+with Snames;         use Snames;
+with Stand;          use Stand;
 
 package body Sem_Cat is
 
@@ -86,14 +88,13 @@ package body Sem_Cat is
    --  Return True if the entity or one of its subcomponents does not support
    --  external streaming.
 
-   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
-   --  (returns false within an instance and within the package body).
-
+   function In_RCI_Declaration return Boolean;
    function In_RT_Declaration return Boolean;
-   --  Determines if current scope is within the declaration of a Remote Types
-   --  unit, for semantic checking purposes.
+   --  Determine if current scope is within the declaration of a Remote Call
+   --  Interface or Remote Types unit, for semantic checking purposes.
+
+   function In_Package_Declaration return Boolean;
+   --  Shared supporting routine for In_RCI_Declaration and In_RT_Declaration
 
    function In_Shared_Passive_Unit return Boolean;
    --  Determines if current scope is within a Shared Passive compilation unit
@@ -186,9 +187,10 @@ package body Sem_Cat is
 
    begin
       --  Intrinsic subprograms are preelaborated, so do not impose any
-      --  categorization dependencies.
+      --  categorization dependencies. Also, ignore categorization
+      --  dependencies when compilation switch -gnatdu is used.
 
-      if Is_Intrinsic_Subprogram (Depended_Entity) then
+      if Is_Intrinsic_Subprogram (Depended_Entity) or else Debug_Flag_U then
          return;
       end if;
 
@@ -263,8 +265,8 @@ package body Sem_Cat is
          --  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))
+         if Is_Internal_Unit (Current_Sem_Unit)
+           and then not Is_Internal_Unit (Main_Unit)
          then
             return;
 
@@ -277,7 +279,7 @@ package body Sem_Cat is
            and then Is_Preelaborated (Depended_Entity)
          then
             Error_Msg_NE
-              ("<must use private with clause for preelaborated unit& ",
+              ("<<must use private with clause for preelaborated unit&",
                N, Depended_Entity);
 
          --  Subunit case
@@ -291,25 +293,23 @@ package body Sem_Cat is
 
          else
             Error_Msg_NE
-              ("<cannot depend on& " &
+              ("<<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);
+            Error_Msg_N
+              ("\<<pure unit cannot depend on non-pure unit", N);
 
          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);
+            Error_Msg_N
+              ("\<<preelaborated unit cannot depend on "
+               & "non-preelaborated unit", N);
          end if;
       end if;
    end Check_Categorization_Dependencies;
@@ -346,16 +346,23 @@ package body Sem_Cat is
 
       if Null_Present (Recdef) then
          return;
-      else
-         Component_Decl := First (Component_Items (Component_List (Recdef)));
       end if;
 
-      while Present (Component_Decl)
-        and then Nkind (Component_Decl) = N_Component_Declaration
-      loop
-         if Present (Expression (Component_Decl))
+      Component_Decl := First (Component_Items (Component_List (Recdef)));
+
+      while Present (Component_Decl) loop
+         if Nkind (Component_Decl) = N_Component_Declaration
+           and then Present (Expression (Component_Decl))
            and then Nkind (Expression (Component_Decl)) /= N_Null
-           and then not Is_Static_Expression (Expression (Component_Decl))
+           and then not Is_OK_Static_Expression (Expression (Component_Decl))
+
+           --  If we're in a predefined unit, we can put whatever we like in a
+           --  preelaborated package, and in fact in some cases it's necessary
+           --  to bend the rules. Ada.Containers.Bounded_Hashed_Maps contains
+           --  some code that would not be considered preelaborable in user
+           --  code, for example.
+
+           and then not In_Predefined_Unit (Component_Decl)
          then
             Error_Msg_Sloc := Sloc (Component_Decl);
             Error_Msg_F
@@ -424,12 +431,13 @@ package body Sem_Cat is
    -------------------------------
 
    function Has_Read_Write_Attributes (E : Entity_Id) return Boolean is
+      Real_Rep : Node_Id;
    begin
       return True
         and then Has_Stream_Attribute_Definition
-                   (E, TSS_Stream_Read,  At_Any_Place => True)
+                   (E, TSS_Stream_Read, Real_Rep, At_Any_Place => True)
         and then Has_Stream_Attribute_Definition
-                   (E, TSS_Stream_Write, At_Any_Place => True);
+                   (E, TSS_Stream_Write, Real_Rep, At_Any_Place => True);
    end Has_Read_Write_Attributes;
 
    -------------------------------------
@@ -439,23 +447,12 @@ package body Sem_Cat is
    function Has_Stream_Attribute_Definition
      (Typ          : Entity_Id;
       Nam          : TSS_Name_Type;
+      Real_Rep     : out Node_Id;
       At_Any_Place : Boolean := False) return Boolean
    is
-      Rep_Item  : Node_Id;
-      Full_Type : Entity_Id := Typ;
+      Rep_Item : Node_Id;
 
    begin
-      --  In the case of a type derived from a private view, any specified
-      --  stream attributes will be attached to the derived type's underlying
-      --  type rather the derived type entity itself (which is itself private).
-
-      if Is_Private_Type (Typ)
-        and then Is_Derived_Type (Typ)
-        and then Present (Full_View (Typ))
-      then
-         Full_Type := Underlying_Type (Typ);
-      end if;
-
       --  We start from the declaration node and then loop until the end of
       --  the list until we find the requested attribute definition clause.
       --  In Ada 2005 mode, clauses are ignored if they are not currently
@@ -463,10 +460,21 @@ package body Sem_Cat is
       --  inserted by the expander at the point where the clause occurs),
       --  unless At_Any_Place is true.
 
-      Rep_Item := First_Rep_Item (Full_Type);
+      Real_Rep := Empty;
+
+      Rep_Item := First_Rep_Item (Typ);
       while Present (Rep_Item) loop
-         if Nkind (Rep_Item) = N_Attribute_Definition_Clause then
-            case Chars (Rep_Item) is
+         Real_Rep := Rep_Item;
+
+         --  If the representation item is an aspect specification, retrieve
+         --  the corresponding pragma or attribute definition.
+
+         if Nkind (Rep_Item) = N_Aspect_Specification then
+            Real_Rep := Aspect_Rep_Item (Rep_Item);
+         end if;
+
+         if Nkind (Real_Rep) = N_Attribute_Definition_Clause then
+            case Chars (Real_Rep) is
                when Name_Read =>
                   exit when Nam = TSS_Stream_Read;
 
@@ -481,23 +489,54 @@ package body Sem_Cat is
 
                when others =>
                   null;
-
             end case;
          end if;
 
          Next_Rep_Item (Rep_Item);
       end loop;
 
-      --  If At_Any_Place is true, return True if the attribute is available
-      --  at any place; if it is false, return True only if the attribute is
-      --  currently visible.
+      --  If not found, and the type is derived from a private view, check
+      --  for a stream attribute inherited from parent. Any specified stream
+      --  attributes will be attached to the derived type's underlying type
+      --  rather the derived type entity itself (which is itself private).
 
-      return Present (Rep_Item)
-        and then (Ada_Version < Ada_2005
-                   or else At_Any_Place
-                   or else not Is_Hidden (Entity (Rep_Item)));
+      if No (Rep_Item)
+        and then Is_Private_Type (Typ)
+        and then Is_Derived_Type (Typ)
+        and then Present (Full_View (Typ))
+      then
+         return Has_Stream_Attribute_Definition
+                  (Underlying_Type (Typ), Nam, Real_Rep, At_Any_Place);
+
+      --  Otherwise, if At_Any_Place is true, return True if the attribute is
+      --  available at any place; if it is false, return True only if the
+      --  attribute is currently visible.
+
+      else
+         return Present (Rep_Item)
+           and then (Ada_Version < Ada_2005
+                      or else At_Any_Place
+                      or else not Is_Hidden (Entity (Rep_Item)));
+      end if;
    end Has_Stream_Attribute_Definition;
 
+   ----------------------------
+   -- In_Package_Declaration --
+   ----------------------------
+
+   function In_Package_Declaration return Boolean is
+      Unit_Kind  : constant Node_Kind :=
+                     Nkind (Unit (Cunit (Current_Sem_Unit)));
+
+   begin
+      --  There are no restrictions on the body of an RCI or RT unit
+
+      return Is_Package_Or_Generic_Package (Current_Scope)
+        and then Unit_Kind /= N_Package_Body
+        and then not In_Package_Body (Current_Scope)
+        and then not In_Instance;
+   end In_Package_Declaration;
+
    ---------------------------
    -- In_Preelaborated_Unit --
    ---------------------------
@@ -522,7 +561,7 @@ package body Sem_Cat is
       --  There are no constraints on the body of Remote_Call_Interface or
       --  Remote_Types packages.
 
-      return (Unit_Entity /= Standard_Standard)
+      return Unit_Entity /= Standard_Standard
         and then (Is_Preelaborated (Unit_Entity)
                     or else Is_Pure (Unit_Entity)
                     or else Is_Shared_Passive (Unit_Entity)
@@ -548,26 +587,10 @@ package body Sem_Cat is
    -- In_RCI_Declaration --
    ------------------------
 
-   function In_RCI_Declaration (N : Node_Id) return Boolean is
-      Unit_Entity : constant Entity_Id := Current_Scope;
-      Unit_Kind   : constant Node_Kind :=
-                      Nkind (Unit (Cunit (Current_Sem_Unit)));
-
+   function In_RCI_Declaration return Boolean is
    begin
-      --  There are no restrictions on the private part or body
-      --  of an RCI unit.
-
-      return Is_Remote_Call_Interface (Unit_Entity)
-        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???
+      return Is_Remote_Call_Interface (Current_Scope)
+        and then In_Package_Declaration;
    end In_RCI_Declaration;
 
    -----------------------
@@ -575,18 +598,8 @@ package body Sem_Cat is
    -----------------------
 
    function In_RT_Declaration return Boolean is
-      Unit_Entity : constant Entity_Id := Current_Scope;
-      Unit_Kind   : constant Node_Kind :=
-                      Nkind (Unit (Cunit (Current_Sem_Unit)));
-
    begin
-      --  There are no restrictions on the body of a Remote Types unit
-
-      return Is_Remote_Types (Unit_Entity)
-        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;
+      return Is_Remote_Types (Current_Scope) and then In_Package_Declaration;
    end In_RT_Declaration;
 
    ----------------------------
@@ -616,9 +629,7 @@ package body Sem_Cat is
 
       E := Current_Scope;
       loop
-         if Is_Subprogram (E)
-              or else
-            Is_Generic_Subprogram (E)
+         if Is_Subprogram_Or_Generic_Subprogram (E)
               or else
             Is_Concurrent_Type (E)
          then
@@ -637,7 +648,9 @@ package body Sem_Cat is
    -------------------------------
 
    function Is_Non_Remote_Access_Type (E : Entity_Id) return Boolean is
-      U_E : constant Entity_Id := Underlying_Type (E);
+      U_E : constant Entity_Id := Underlying_Type (Base_Type (E));
+      --  Use full view of base type to handle subtypes properly.
+
    begin
       if No (U_E) then
 
@@ -683,50 +696,25 @@ package body Sem_Cat is
    -------------------------------------
 
    procedure Set_Categorization_From_Pragmas (N : Node_Id) is
-      P   : constant Node_Id := Parent (N);
-      S   : constant Entity_Id := Current_Scope;
+      P : constant Node_Id := Parent (N);
 
-      procedure Set_Parents (Visibility : Boolean);
-         --  If this is a child instance, the parents are not immediately
-         --  visible during analysis. Make them momentarily visible so that
-         --  the argument of the pragma can be resolved properly, and reset
-         --  afterwards.
+      procedure Make_Parents_Visible_And_Process_Pragmas (Par : Entity_Id);
+      --  Parents might not be immediately visible during analysis. Make
+      --  them momentarily visible so that the argument of the pragma can
+      --  be resolved properly, process pragmas and restore the previous
+      --  visibility.
 
-      -----------------
-      -- Set_Parents --
-      -----------------
-
-      procedure Set_Parents (Visibility : Boolean) is
-         Par : Entity_Id;
-      begin
-         Par := Scope (S);
-         while Present (Par) and then Par /= Standard_Standard loop
-            Set_Is_Immediately_Visible (Par, Visibility);
-            Par := Scope (Par);
-         end loop;
-      end Set_Parents;
-
-   --  Start of processing for Set_Categorization_From_Pragmas
-
-   begin
-      --  Deal with categorization pragmas in Pragmas of Compilation_Unit.
-      --  The purpose is to set categorization flags before analyzing the
-      --  unit itself, so as to diagnose violations of categorization as
-      --  we process each declaration, even though the pragma appears after
-      --  the unit.
+      procedure Process_Categorization_Pragmas;
+      --  Process categorization pragmas, if any
 
-      if Nkind (P) /= N_Compilation_Unit then
-         return;
-      end if;
+      ------------------------------------
+      -- Process_Categorization_Pragmas --
+      ------------------------------------
 
-      declare
+      procedure Process_Categorization_Pragmas is
          PN : Node_Id;
 
       begin
-         if Is_Child_Unit (S) and then Is_Generic_Instance (S) then
-            Set_Parents (True);
-         end if;
-
          PN := First (Pragmas_After (Aux_Decls_Node (P)));
          while Present (PN) loop
 
@@ -735,23 +723,65 @@ package body Sem_Cat is
 
             if Nkind (PN) = N_Pragma then
                case Get_Pragma_Id (PN) is
-                  when Pragma_All_Calls_Remote   |
-                    Pragma_Preelaborate          |
-                    Pragma_Pure                  |
-                    Pragma_Remote_Call_Interface |
-                    Pragma_Remote_Types          |
-                    Pragma_Shared_Passive        => Analyze (PN);
-                  when others                    => null;
+                  when Pragma_All_Calls_Remote
+                     | Pragma_Preelaborate
+                     | Pragma_Pure
+                     | Pragma_Remote_Call_Interface
+                     | Pragma_Remote_Types
+                     | Pragma_Shared_Passive
+                  =>
+                     Analyze (PN);
+
+                  when others =>
+                     null;
                end case;
             end if;
 
             Next (PN);
          end loop;
+      end Process_Categorization_Pragmas;
+
+      ----------------------------------------------
+      -- Make_Parents_Visible_And_Process_Pragmas --
+      ----------------------------------------------
 
-         if Is_Child_Unit (S) and then Is_Generic_Instance (S) then
-            Set_Parents (False);
+      procedure Make_Parents_Visible_And_Process_Pragmas (Par : Entity_Id) is
+      begin
+         --  When we reached the Standard scope, then just process pragmas
+
+         if Par = Standard_Standard then
+            Process_Categorization_Pragmas;
+
+         --  Otherwise make the current scope momentarily visible, recurse
+         --  into its enclosing scope, and restore the visibility. This is
+         --  required for child units that are instances of generic parents.
+
+         else
+            declare
+               Save_Is_Immediately_Visible : constant Boolean :=
+                 Is_Immediately_Visible (Par);
+            begin
+               Set_Is_Immediately_Visible (Par);
+               Make_Parents_Visible_And_Process_Pragmas (Scope (Par));
+               Set_Is_Immediately_Visible (Par, Save_Is_Immediately_Visible);
+            end;
          end if;
-      end;
+      end Make_Parents_Visible_And_Process_Pragmas;
+
+   --  Start of processing for Set_Categorization_From_Pragmas
+
+   begin
+      --  Deal with categorization pragmas in Pragmas of Compilation_Unit.
+      --  The purpose is to set categorization flags before analyzing the
+      --  unit itself, so as to diagnose violations of categorization as
+      --  we process each declaration, even though the pragma appears after
+      --  the unit.
+
+      if Nkind (P) /= N_Compilation_Unit then
+         return;
+      end if;
+
+      Make_Parents_Visible_And_Process_Pragmas (Scope (Current_Scope));
    end Set_Categorization_From_Pragmas;
 
    -----------------------------------
@@ -763,15 +793,20 @@ package body Sem_Cat is
       Specification : Node_Id := Empty;
 
    begin
-      Set_Is_Pure
-        (E, Is_Pure (Scop) and then Is_Library_Level_Entity (E));
+      --  Do not modify the purity of an internally generated entity if it has
+      --  been explicitly marked as pure for optimization purposes.
+
+      if not Has_Pragma_Pure_Function (E) then
+         Set_Is_Pure
+           (E, Is_Pure (Scop) and then Is_Library_Level_Entity (E));
+      end if;
 
       if not Is_Remote_Call_Interface (E) then
-         if Ekind (E) in Subprogram_Kind then
+         if Is_Subprogram (E) then
             Declaration := Unit_Declaration_Node (E);
 
-            if Nkind_In (Declaration, N_Subprogram_Body,
-                                      N_Subprogram_Renaming_Declaration)
+            if Nkind (Declaration) in
+                 N_Subprogram_Body | N_Subprogram_Renaming_Declaration
             then
                Specification := Corresponding_Spec (Declaration);
             end if;
@@ -816,7 +851,8 @@ package body Sem_Cat is
       Discriminant_Spec := First (L);
       while Present (Discriminant_Spec) loop
          if Present (Expression (Discriminant_Spec))
-           and then not Is_Static_Expression (Expression (Discriminant_Spec))
+           and then
+             not Is_OK_Static_Expression (Expression (Discriminant_Spec))
          then
             return False;
          end if;
@@ -929,8 +965,7 @@ package body Sem_Cat is
 
          if Is_Private_Type (T)
            and then not Has_Pragma_Preelab_Init (T)
-           and then not Is_Internal_File_Name
-                          (Unit_File_Name (Get_Source_Unit (N)))
+           and then not In_Internal_Unit (N)
          then
             Error_Msg_N
               ("private ancestor type not allowed in preelaborated unit", A);
@@ -980,7 +1015,7 @@ package body Sem_Cat is
       --  Body of RCI unit does not need validation
 
       if Is_Remote_Call_Interface (E)
-        and then Nkind_In (N, N_Package_Body, N_Subprogram_Body)
+        and then Nkind (N) in N_Package_Body | N_Subprogram_Body
       then
          return;
       end if;
@@ -995,17 +1030,23 @@ package body Sem_Cat is
          Item := First (Context_Items (P));
          while Present (Item) loop
             if Nkind (Item) = N_With_Clause
-              and then not (Implicit_With (Item)
-                             or else Limited_Present (Item)
+              and then
+                not (Implicit_With (Item)
+                      or else Limited_Present (Item)
 
-                             --  Skip if error already posted on the WITH
-                             --  clause (in which case the Name attribute
-                             --  may be invalid). In particular, this fixes
-                             --  the problem of hanging in the presence of a
-                             --  WITH clause on a child that is an illegal
-                             --  generic instantiation.
+                      --  Skip if error already posted on the WITH clause (in
+                      --  which case the Name attribute may be invalid). In
+                      --  particular, this fixes the problem of hanging in the
+                      --  presence of a WITH clause on a child that is an
+                      --  illegal generic instantiation.
 
-                             or else Error_Posted (Item))
+                      or else Error_Posted (Item))
+              and then
+                not (Try_Semantics
+
+                      --  Skip processing malformed trees
+
+                      and then Nkind (Name (Item)) not in N_Has_Entity)
             then
                Entity_Of_Withed := Entity (Name (Item));
                Check_Categorization_Dependencies
@@ -1039,7 +1080,8 @@ package body Sem_Cat is
            and then not Private_Present (P)
            and then not Is_Remote_Call_Interface (E)
          then
-            Error_Msg_N ("public child of rci unit must also be rci unit", N);
+            Error_Msg_N
+              ("public child of 'R'C'I unit must also be 'R'C'I unit", N);
          end if;
       end if;
    end Validate_Categorization_Dependency;
@@ -1067,13 +1109,12 @@ package body Sem_Cat is
       --  Note that the 10.2.1(9) restrictions are not relevant to us anyway.
       --  We have to enforce them for RM compatibility, but we have no trouble
       --  accepting these objects and doing the right thing. Note that there is
-      --  no requirement that Preelaborate not actually generate any code!
+      --  no requirement that Preelaborate not actually generate any code.
 
       if In_Preelaborated_Unit
         and then not Debug_Flag_PP
         and then Comes_From_Source (E)
-        and then not
-          Is_Internal_File_Name (Unit_File_Name (Get_Source_Unit (E)))
+        and then not In_Internal_Unit (E)
         and then (not Inside_A_Generic
                    or else Present (Enclosing_Generic_Body (E)))
         and then not Is_Protected_Type (Etype (E))
@@ -1103,7 +1144,7 @@ package body Sem_Cat is
 
                Error_Msg_Warn := GNAT_Mode;
                Error_Msg_N
-                 ("<statements not allowed in preelaborated unit", Item);
+                 ("<<statements not allowed in preelaborated unit", Item);
 
                exit;
             end if;
@@ -1226,7 +1267,14 @@ package body Sem_Cat is
                   --  means that a pragma Preelaborable_Initialization was
                   --  given for the private type.
 
-                  if Has_Preelaborable_Initialization (Ent) then
+                  if Relaxed_RM_Semantics then
+
+                     --  In relaxed mode, do not issue these messages, this
+                     --  is basically similar to the GNAT_Mode test below.
+
+                     null;
+
+                  elsif Has_Preelaborable_Initialization (Ent) then
 
                      --  But for the predefined units, we will ignore this
                      --  status unless we are in Ada 2005 mode since we want
@@ -1361,20 +1409,22 @@ package body Sem_Cat is
       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 not In_Private_Part (Id) then
 
-      elsif In_RCI_Declaration (N) then
-         Error_Msg_N ("visible variable not allowed in 'R'C'I unit", N);
+         --  The visible part of an RCI library unit must not contain the
+         --  declaration of a variable (RM E.1.3(9)).
 
-      --  The visible part of a Shared Passive library unit must not contain
-      --  the declaration of a variable (RM E.2.2(7))
+         if In_RCI_Declaration then
+            Error_Msg_N ("visible variable not allowed in 'R'C'I unit", N);
 
-      elsif In_RT_Declaration and then not In_Private_Part (Id) then
-         Error_Msg_N
-           ("visible variable not allowed in remote types unit", N);
-      end if;
+         --  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
+            Error_Msg_N
+              ("visible variable not allowed in remote types unit", N);
+         end if;
+      end if;
    end Validate_Object_Declaration;
 
    -----------------------------
@@ -1469,8 +1519,8 @@ package body Sem_Cat is
 
             null;
 
-         elsif Ekind_In (Param_Type, E_Anonymous_Access_Type,
-                                     E_Anonymous_Access_Subprogram_Type)
+         elsif Ekind (Param_Type) in E_Anonymous_Access_Type
+                                   | E_Anonymous_Access_Subprogram_Type
          then
             --  From RM E.2.2(14), no anonymous access parameter other than
             --  controlling ones may be used (because an anonymous access
@@ -1543,21 +1593,21 @@ package body Sem_Cat is
          if Comes_From_Source (E) then
             if Is_Limited_Type (E) then
                Error_Msg_N
-                 ("limited type not allowed in rci unit", Parent (E));
+                 ("limited type not allowed in 'R'C'I unit", Parent (E));
                Explain_Limited_Type (E, Parent (E));
 
-            elsif Ekind_In (E, E_Generic_Function,
-                               E_Generic_Package,
-                               E_Generic_Procedure)
+            elsif Ekind (E) in E_Generic_Function
+                             | E_Generic_Package
+                             | E_Generic_Procedure
             then
-               Error_Msg_N ("generic declaration not allowed in rci unit",
+               Error_Msg_N ("generic declaration not allowed in 'R'C'I unit",
                  Parent (E));
 
             elsif (Ekind (E) = E_Function or else Ekind (E) = E_Procedure)
               and then Has_Pragma_Inline (E)
             then
                Error_Msg_N
-                 ("inlined subprogram not allowed in rci unit", Parent (E));
+                 ("inlined subprogram not allowed in 'R'C'I unit", Parent (E));
 
             --  Inner packages that are renamings need not be checked. Generic
             --  RCI packages are subject to the checks, but entities that come
@@ -1589,7 +1639,7 @@ package body Sem_Cat is
    procedure Validate_RCI_Subprogram_Declaration (N : Node_Id) is
       K               : constant Node_Kind := Nkind (N);
       Profile         : List_Id;
-      Id              : Node_Id;
+      Id              : constant Entity_Id := Defining_Entity (N);
       Param_Spec      : Node_Id;
       Param_Type      : Entity_Id;
       Error_Node      : Node_Id := N;
@@ -1602,22 +1652,23 @@ package body Sem_Cat is
       --    1. from Analyze_Subprogram_Declaration.
       --    2. from Validate_Object_Declaration (access to subprogram).
 
-      if not (Comes_From_Source (N) and then In_RCI_Declaration (N)) then
+      if not (Comes_From_Source (N)
+                and then In_RCI_Declaration
+                and then not In_Private_Part (Scope (Id)))
+      then
          return;
       end if;
 
       if K = N_Subprogram_Declaration then
-         Id := Defining_Unit_Name (Specification (N));
          Profile := Parameter_Specifications (Specification (N));
 
-      else pragma Assert (K = N_Object_Declaration);
+      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
            and then Nkind (Parent (Etype (Id))) = N_Full_Type_Declaration
            and then Ekind (Etype (Id)) = E_Access_Subprogram_Type
@@ -1645,12 +1696,10 @@ package body Sem_Cat is
 
                --  Report error only if declaration is in source program
 
-               if Comes_From_Source
-                 (Defining_Entity (Specification (N)))
-               then
+               if Comes_From_Source (Id) then
                   Error_Msg_N
                     ("subprogram in 'R'C'I unit cannot have access parameter",
-                      Error_Node);
+                     Error_Node);
                end if;
 
             --  For a limited private type parameter, we check only the private
@@ -1673,8 +1722,15 @@ package body Sem_Cat is
 
             Next (Param_Spec);
          end loop;
+      end if;
 
-         --  No check on return type???
+      if Ekind (Id) = E_Function
+        and then Ekind (Etype (Id)) = E_Anonymous_Access_Type
+        and then Comes_From_Source (Id)
+      then
+         Error_Msg_N
+           ("function in 'R'C'I unit cannot have access result",
+             Error_Node);
       end if;
    end Validate_RCI_Subprogram_Declaration;
 
@@ -1691,17 +1747,18 @@ package body Sem_Cat is
       --  the given node is N_Access_To_Object_Definition.
 
       if not Comes_From_Source (T)
-        or else (not In_RCI_Declaration (Parent (T))
-                  and then not In_RT_Declaration)
+        or else (not In_RCI_Declaration and then not In_RT_Declaration)
       then
          return;
       end if;
 
-      --  An access definition in the private part of a Remote Types package
-      --  may be legal if it has user-defined Read and Write attributes. This
-      --  will be checked at the end of the package spec processing.
+      --  An access definition in the private part of a package is not a
+      --  remote access type. Restrictions related to external streaming
+      --  support for non-remote access types are enforced elsewhere. Note
+      --  that In_Private_Part is never set on type entities: check flag
+      --  on enclosing scope.
 
-      if In_RT_Declaration and then In_Private_Part (Scope (T)) then
+      if In_Private_Part (Scope (T)) then
          return;
       end if;
 
@@ -1714,7 +1771,7 @@ package body Sem_Cat is
       if Ekind (T) /= E_General_Access_Type
         or else not Is_Class_Wide_Type (Designated_Type (T))
       then
-         if In_RCI_Declaration (Parent (T)) then
+         if In_RCI_Declaration then
             Error_Msg_N
               ("error in access type in Remote_Call_Interface unit", T);
          else
@@ -1771,7 +1828,17 @@ package body Sem_Cat is
 
       --    4. called from sem_res Resolve_Actuals
 
-      if K = N_Attribute_Reference then
+      if K = N_Attribute_Definition_Clause then
+         E := Etype (Entity (N));
+
+         if Is_Remote_Access_To_Class_Wide_Type (E) then
+            Error_Msg_Name_1 := Chars (N);
+            Error_Msg_N
+              ("cannot specify% aspect for a remote operand", N);
+            return;
+         end if;
+
+      elsif K = N_Attribute_Reference then
          E := Etype (Prefix (N));
 
          if Is_Remote_Access_To_Class_Wide_Type (E) then
@@ -1927,14 +1994,15 @@ package body Sem_Cat is
 
       Typ := First_Entity (Name_U);
       while Present (Typ) and then Typ /= First_Priv_Ent loop
-         U_Typ := Underlying_Type (Typ);
+         U_Typ := Underlying_Type (Base_Type (Typ));
 
          if No (U_Typ) then
             U_Typ := Typ;
          end if;
 
-         if Comes_From_Source (Typ) and then Is_Type (Typ) then
-
+         if Comes_From_Source (Typ) and then Is_Type (Typ)
+           and then Ekind (Typ) /= E_Incomplete_Type
+         then
             --  Check that the type can be meaningfully transmitted to another
             --  partition (E.2.2(8)).
 
@@ -2042,7 +2110,8 @@ package body Sem_Cat is
    ---------------------------------
 
    procedure Validate_Static_Object_Name (N : Node_Id) is
-      E : Entity_Id;
+      E   : Entity_Id;
+      Val : Node_Id;
 
       function Is_Primary (N : Node_Id) return Boolean;
       --  Determine whether node is syntactically a primary in an expression
@@ -2060,30 +2129,38 @@ package body Sem_Cat is
 
       begin
          case K is
-            when N_Op | N_Membership_Test =>
-               return True;
-
             when N_Aggregate
                | N_Component_Association
-               | N_Index_Or_Discriminant_Constraint =>
+               | N_Index_Or_Discriminant_Constraint
+               | N_Membership_Test
+               | N_Op
+               | N_Range
+            =>
                return True;
 
             when N_Attribute_Reference =>
-               return Attribute_Name (Parent (N)) /= Name_Address
-                 and then Attribute_Name (Parent (N)) /= Name_Access
-                 and then Attribute_Name (Parent (N)) /= Name_Unchecked_Access
-                 and then
-                   Attribute_Name (Parent (N)) /= Name_Unrestricted_Access;
+               declare
+                  Attr : constant Name_Id := Attribute_Name (Parent (N));
+
+               begin
+                  return     Attr /= Name_Address
+                    and then Attr /= Name_Access
+                    and then Attr /= Name_Unchecked_Access
+                    and then Attr /= Name_Unrestricted_Access;
+               end;
 
             when N_Indexed_Component =>
-               return (N /= Prefix (Parent (N))
-                 or else Is_Primary (Parent (N)));
+               return N /= Prefix (Parent (N)) or else Is_Primary (Parent (N));
 
-            when N_Qualified_Expression | N_Type_Conversion =>
+            when N_Qualified_Expression
+               | N_Type_Conversion
+            =>
                return Is_Primary (Parent (N));
 
-            when N_Assignment_Statement | N_Object_Declaration =>
-               return (N = Expression (Parent (N)));
+            when N_Assignment_Statement
+               | N_Object_Declaration
+            =>
+               return N = Expression (Parent (N));
 
             when N_Selected_Component =>
                return Is_Primary (Parent (N));
@@ -2127,11 +2204,14 @@ package body Sem_Cat is
       --  Error if the name is a primary in an expression. The parent must not
       --  be an operator, or a selected component or an indexed component that
       --  is itself a primary. Entities that are actuals do not need to be
-      --  checked, because the call itself will be diagnosed.
+      --  checked, because the call itself will be diagnosed. Entities in a
+      --  generic unit or within a preanalyzed expression are not checked:
+      --  only their use in executable code matters.
 
       if Is_Primary (N)
         and then (not Inside_A_Generic
                    or else Present (Enclosing_Generic_Body (N)))
+        and then not In_Spec_Expression
       then
          if Ekind (Entity (N)) = E_Variable
            or else Ekind (Entity (N)) in Formal_Object_Kind
@@ -2145,9 +2225,10 @@ package body Sem_Cat is
          elsif Ekind (Entity (N)) = E_Constant
            and then not Is_Static_Expression (N)
          then
-            E := Entity (N);
+            E   := Entity (N);
+            Val := Constant_Value (E);
 
-            if Is_Internal_File_Name (Unit_File_Name (Get_Source_Unit (N)))
+            if In_Internal_Unit (N)
               and then
                 Enclosing_Comp_Unit_Node (N) /= Enclosing_Comp_Unit_Node (E)
               and then (Is_Preelaborated (Scope (E))
@@ -2156,20 +2237,36 @@ package body Sem_Cat is
                                    and then Is_Entity_Name (Renamed_Object (E))
                                    and then
                                      (Is_Preelaborated
-                                       (Scope (Renamed_Object (E)))
-                                         or else
-                                           Is_Pure (Scope
-                                             (Renamed_Object (E))))))
+                                        (Scope (Renamed_Object (E)))
+                                       or else
+                                         Is_Pure
+                                           (Scope (Renamed_Object (E))))))
+            then
+               null;
+
+            --  If the value of the constant is a local variable that renames
+            --  an aggregate, this is in itself legal. The aggregate may be
+            --  expanded into a loop, but this does not affect preelaborability
+            --  in itself. If some aggregate components are non-static, that is
+            --  to say if they involve non static primaries, they will be
+            --  flagged when analyzed.
+
+            elsif Present (Val)
+              and then Is_Entity_Name (Val)
+              and then Is_Array_Type (Etype (Val))
+              and then not Comes_From_Source (Val)
+              and then Nkind (Original_Node (Val)) = N_Aggregate
             then
                null;
 
             --  This is the error case
 
             else
-               --  In GNAT mode, this is just a warning, to allow it to be
-               --  judiciously turned off. Otherwise it is a real error.
+               --  In GNAT mode or Relaxed RM Semantic mode, this is just a
+               --  warning, to allow it to be judiciously turned off.
+               --  Otherwise it is a real error.
 
-               if GNAT_Mode then
+               if GNAT_Mode or Relaxed_RM_Semantics then
                   Error_Msg_N
                     ("??non-static constant in preelaborated unit", N);
                else
This page took 0.059833 seconds and 5 git commands to generate.