From: Eric Botcazou <ebotca...@adacore.com>

The first cleanup is to expose a consistent interface from Sem_Ch13 for the
analysis of aspects at various points of the program.  The second cleanup is
to fix the awkward implementation of the analysis of the specification for
the aspects Stable_Properties, Designated_Storage_Model, Storage_Model_Type
and Aggregate, which are always delayed, and the incorrect placement of that
of the aspect Local_Restrictions, which is never delayed.

gcc/ada/

        * freeze.adb (Freeze_All): Call Check_Aspects_At_End_Of_Declarations
        to perform the visibility check for aspects.
        * sem_ch13.ads (Check_Aspects_At_End_Of_Declarations): Declare.
        (Check_Aspect_At_Freeze_Point): Move to...
        (Check_Aspect_At_End_Of_Declarations): Move to...
        * sem_ch13.adb  (Check_Aspect_At_Freeze_Point): ...here.
        (Check_Aspect_At_End_Of_Declarations): ...here.
        (Analyze_Aspect_Specifications): Remove peculiar processing for
        Stable_Properties, Designated_Storage_Model, Storage_Model_Type
        and Aggregate.  Move that of Local_Restrictions around.  Reset
        Aitem at the beginning of the loop for each aspect.
        (Check_Aspects_At_End_Of_Declarations): New procedure.

Tested on x86_64-pc-linux-gnu, committed on master.

---
 gcc/ada/freeze.adb   | 17 +--------
 gcc/ada/sem_ch13.adb | 87 ++++++++++++++++++++++++++------------------
 gcc/ada/sem_ch13.ads | 14 +++----
 3 files changed, 58 insertions(+), 60 deletions(-)

diff --git a/gcc/ada/freeze.adb b/gcc/ada/freeze.adb
index c4c524f4685..523b026cc21 100644
--- a/gcc/ada/freeze.adb
+++ b/gcc/ada/freeze.adb
@@ -2645,22 +2645,7 @@ package body Freeze is
             --  for a description of how we handle aspect visibility).
 
             elsif Has_Delayed_Aspects (E) then
-               declare
-                  Ritem : Node_Id;
-
-               begin
-                  Ritem := First_Rep_Item (E);
-                  while Present (Ritem) loop
-                     if Nkind (Ritem) = N_Aspect_Specification
-                       and then Entity (Ritem) = E
-                       and then Is_Delayed_Aspect (Ritem)
-                     then
-                        Check_Aspect_At_End_Of_Declarations (Ritem);
-                     end if;
-
-                     Next_Rep_Item (Ritem);
-                  end loop;
-               end;
+               Check_Aspects_At_End_Of_Declarations (E);
             end if;
 
             --  If an incomplete type is still not frozen, this may be a
diff --git a/gcc/ada/sem_ch13.adb b/gcc/ada/sem_ch13.adb
index d065dd8dfda..46a359fd7d6 100644
--- a/gcc/ada/sem_ch13.adb
+++ b/gcc/ada/sem_ch13.adb
@@ -150,6 +150,15 @@ package body Sem_Ch13 is
    --  is inserted before the freeze node, and the body of the function is
    --  inserted after the freeze node.
 
+   procedure Check_Aspect_At_End_Of_Declarations (ASN : Node_Id);
+   --  Performs the processing of an aspect at the freeze all point and issues
+   --  appropriate error messages if the visibility has indeed changed. ASN is
+   --  the N_Aspect_Specification node for the aspect.
+
+   procedure Check_Aspect_At_Freeze_Point (ASN : Node_Id);
+   --  Performs the processing of an aspect at the freeze point. ASN is the
+   --  N_Aspect_Specification node for the aspect.
+
    procedure Check_Pool_Size_Clash (Ent : Entity_Id; SP, SS : Node_Id);
    --  Called if both Storage_Pool and Storage_Size attribute definition
    --  clauses (SP and SS) are present for entity Ent. Issue error message.
@@ -1669,7 +1678,6 @@ package body Sem_Ch13 is
       --  Local variables
 
       Aspect : Node_Id;
-      Aitem  : Node_Id := Empty;
       Ent    : Node_Id;
 
       L : constant List_Id := Aspect_Specifications (N);
@@ -1722,7 +1730,12 @@ package body Sem_Ch13 is
             Loc  : constant Source_Ptr := Sloc (Aspect);
             Nam  : constant Name_Id    := Chars (Id);
             A_Id : constant Aspect_Id  := Get_Aspect_Id (Nam);
+
+            Aitem : Node_Id := Empty;
+            --  The associated N_Pragma or N_Attribute_Definition_Clause
+
             Anod : Node_Id;
+            --  An auxiliary node
 
             Delay_Required : Boolean;
             --  Set False if delay is not required
@@ -2949,19 +2962,6 @@ package body Sem_Ch13 is
                   end if;
             end case;
 
-            if Delay_Required
-               and then (A_Id = Aspect_Stable_Properties
-                          or else A_Id = Aspect_Designated_Storage_Model
-                          or else A_Id = Aspect_Storage_Model_Type
-                          or else A_Id = Aspect_Aggregate)
-               --  ??? It seems like we should do this for all aspects, not
-               --  just these, but that causes as-yet-undiagnosed regressions.
-
-            then
-               Set_Has_Delayed_Aspects (E);
-               Set_Is_Delayed_Aspect (Aspect);
-            end if;
-
             --  Check 13.1(9.2/5): A representation aspect of a subtype or type
             --  shall not be specified (whether by a representation item or an
             --  aspect_specification) before the type is completely defined
@@ -3307,6 +3307,9 @@ package body Sem_Ch13 is
 
                --  External_Name, Link_Name
 
+               --  Only the legality checks are done during the analysis, thus
+               --  no delay is required.
+
                when Aspect_External_Name
                   | Aspect_Link_Name
                =>
@@ -4126,30 +4129,20 @@ package body Sem_Ch13 is
                      end if;
                   end if;
 
-                  Aitem := Empty;
-
                when Aspect_Aggregate =>
                   --  We will be checking that the aspect is not specified on a
                   --  non-array type in Check_Aspect_At_Freeze_Point
 
                   Validate_Aspect_Aggregate (Expr);
-                  Record_Rep_Item (E, Aspect);
-                  goto Continue;
-
-               when Aspect_Local_Restrictions =>
-                  Validate_Aspect_Local_Restrictions (E, Expr);
-                  Record_Rep_Item (E, Aspect);
-                  goto Continue;
 
                when Aspect_Stable_Properties =>
                   Validate_Aspect_Stable_Properties
                     (E, Expr, Class_Present => Class_Present (Aspect));
-                  Record_Rep_Item (E, Aspect);
-                  goto Continue;
 
                when Aspect_Designated_Storage_Model =>
                   if not All_Extensions_Allowed then
                      Error_Msg_GNAT_Extension ("aspect %", Loc);
+                     goto Continue;
 
                   elsif not Is_Type (E)
                     or else Ekind (E) /= E_Access_Type
@@ -4157,14 +4150,13 @@ package body Sem_Ch13 is
                      Error_Msg_N
                        ("can only be specified for pool-specific access type",
                         Aspect);
+                     goto Continue;
                   end if;
 
-                  Record_Rep_Item (E, Aspect);
-                  goto Continue;
-
                when Aspect_Storage_Model_Type =>
                   if not All_Extensions_Allowed then
                      Error_Msg_GNAT_Extension ("aspect %", Loc);
+                     goto Continue;
 
                   elsif not Is_Type (E)
                     or else not Is_Immutably_Limited_Type (E)
@@ -4172,11 +4164,9 @@ package body Sem_Ch13 is
                      Error_Msg_N
                        ("can only be specified for immutably limited type",
                         Aspect);
+                     goto Continue;
                   end if;
 
-                  Record_Rep_Item (E, Aspect);
-                  goto Continue;
-
                when Aspect_Integer_Literal
                   | Aspect_Real_Literal
                   | Aspect_String_Literal
@@ -4193,16 +4183,13 @@ package body Sem_Ch13 is
                        (No_Implementation_Aspect_Specifications, N);
                   end if;
 
-                  Aitem := Empty;
-
                --  Case 3b: The aspects listed below don't correspond to
                --  pragmas/attributes and don't need delayed analysis.
 
                --  Implicit_Dereference
 
-               --  For Implicit_Dereference, External_Name and Link_Name, only
-               --  the legality checks are done during the analysis, thus no
-               --  delay is required.
+               --  Only the legality checks are done during the analysis, thus
+               --  no delay is required.
 
                when Aspect_Implicit_Dereference =>
                   Analyze_Aspect_Implicit_Dereference;
@@ -4220,6 +4207,11 @@ package body Sem_Ch13 is
                   Analyze_Aspect_Dimension_System (N, Id, Expr);
                   goto Continue;
 
+               when Aspect_Local_Restrictions =>
+                  Validate_Aspect_Local_Restrictions (E, Expr);
+                  Record_Rep_Item (E, Aspect);
+                  goto Continue;
+
                --  Case 4: Aspects requiring special handling
 
                --  Pre/Post/Test_Case/Contract_Cases/Always_Terminates/
@@ -4806,6 +4798,7 @@ package body Sem_Ch13 is
                   end if;
                end;
             end if;
+
          exception
             when Aspect_Exit => null;
          end Analyze_One_Aspect;
@@ -11157,6 +11150,28 @@ package body Sem_Ch13 is
       end if;
    end Check_Aspect_At_End_Of_Declarations;
 
+   ------------------------------------------
+   -- Check_Aspects_At_End_Of_Declarations --
+   ------------------------------------------
+
+   procedure Check_Aspects_At_End_Of_Declarations (E : Entity_Id) is
+      ASN : Node_Id;
+
+   begin
+      ASN := First_Rep_Item (E);
+
+      while Present (ASN) loop
+         if Nkind (ASN) = N_Aspect_Specification
+           and then Entity (ASN) = E
+           and then Is_Delayed_Aspect (ASN)
+         then
+            Check_Aspect_At_End_Of_Declarations (ASN);
+         end if;
+
+         Next_Rep_Item (ASN);
+      end loop;
+   end Check_Aspects_At_End_Of_Declarations;
+
    ----------------------------------
    -- Check_Aspect_At_Freeze_Point --
    ----------------------------------
diff --git a/gcc/ada/sem_ch13.ads b/gcc/ada/sem_ch13.ads
index 3c48a493c75..2bdca957826 100644
--- a/gcc/ada/sem_ch13.ads
+++ b/gcc/ada/sem_ch13.ads
@@ -312,18 +312,16 @@ package Sem_Ch13 is
    --  Quite an awkward approach, but this is an awkard requirement
 
    procedure Analyze_Aspects_At_Freeze_Point (E : Entity_Id);
-   --  Analyze all the delayed aspects for entity E at freezing point. This
+   --  Analyzes all the delayed aspects for entity E at freezing point. This
    --  includes dealing with inheriting delayed aspects from the parent type
-   --  in the case where a derived type is frozen.
+   --  in the case where a derived type is frozen. Callers should check that
+   --  Has_Delayed_Aspects (E) is True before calling this routine.
 
-   procedure Check_Aspect_At_Freeze_Point (ASN : Node_Id);
-   --  Performs the processing described above at the freeze point, ASN is the
-   --  N_Aspect_Specification node for the aspect.
-
-   procedure Check_Aspect_At_End_Of_Declarations (ASN : Node_Id);
+   procedure Check_Aspects_At_End_Of_Declarations (E : Entity_Id);
    --  Performs the processing described above at the freeze all point, and
    --  issues appropriate error messages if the visibility has indeed changed.
-   --  Again, ASN is the N_Aspect_Specification node for the aspect.
+   --  Callers should check that Has_Delayed_Aspects (E) is True before calling
+   --  this routine.
 
    procedure Inherit_Aspects_At_Freeze_Point (Typ : Entity_Id);
    --  Given an entity Typ that denotes a derived type or a subtype, this
-- 
2.45.1

Reply via email to