From: Javier Miranda <[email protected]>

Enable this language extension using -gnat.u, and extend the
current support to handle derivations of types that have
Unsigned_Base_Range aspect.

gcc/ada/ChangeLog:

        * aspects.adb (Get_Aspect_Id): Enable aspect Unsigned_Base_Range
        using -gnatd.u
        * debug.adb (Debug_Flag_Dot_U): Document this switch.
        * einfo-utils.adb (Is_Modular_Integer_Type): Return True if
        the entity is a modular integer type and its base type does
        not have the attribute has_unsigned_base_range_aspect.
        (Is_Signed_Integer_Type): Return True if the entity is a signed
        integer type, or it is a modular integer type and its base type
        has the attribute has_unsigned_base_range_aspect.
        * einfo.ads (E_Modular_Integer_Type): Add documentation of
        Has_Unsigned_Base_Range_Aspect.
        * par-ch4.adb (Scan_Apostrophe): Enable attribute Unsigned_Base_Range
        using -gnatd.u
        * sem_ch13.adb (Analyze_One_Aspect): Check general language
        restrictions on aspect Unsigned_Base_Range. For Unsigned_Base_Range
        aspect, do not delay the generation of the pragma becase we need
        to process it before any type or subtype derivation is analyzed.
        * sem_ch3.adb (Build_Scalar_Bound): Disable code analyzing the
        bound with the base type of the parent type because, for unsigned
        base range types, their base type is a modular type but their
        type is a signed integer type.
        * sem_prag.adb (Analyze_Pragma): Enable pragma Unsigned_Base_Range
        using -gnatd.u. Check more errors on Unsigned_Base_Range pragma,
        and create the new base type only when required.

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

---
 gcc/ada/aspects.adb     |  5 ++++-
 gcc/ada/debug.adb       |  5 +++--
 gcc/ada/einfo-utils.adb |  8 ++++++--
 gcc/ada/einfo.ads       |  1 +
 gcc/ada/par-ch4.adb     |  3 ++-
 gcc/ada/sem_ch13.adb    |  8 ++++++++
 gcc/ada/sem_ch3.adb     |  8 +++++++-
 gcc/ada/sem_prag.adb    | 38 ++++++++++++++++++++++++++------------
 8 files changed, 57 insertions(+), 19 deletions(-)

diff --git a/gcc/ada/aspects.adb b/gcc/ada/aspects.adb
index c9eaea1b7f9..aecbbe27073 100644
--- a/gcc/ada/aspects.adb
+++ b/gcc/ada/aspects.adb
@@ -24,6 +24,7 @@
 ------------------------------------------------------------------------------
 
 with Atree;          use Atree;
+with Debug;          use Debug;
 with Einfo;          use Einfo;
 with Einfo.Entities; use Einfo.Entities;
 with Einfo.Utils;    use Einfo.Utils;
@@ -282,7 +283,9 @@ package body Aspects is
    begin
       --  Aspect Unsigned_Base_Range temporarily disabled
 
-      if Name = Name_Unsigned_Base_Range then
+      if Name = Name_Unsigned_Base_Range
+        and then not Debug_Flag_Dot_U
+      then
          return No_Aspect;
       end if;
 
diff --git a/gcc/ada/debug.adb b/gcc/ada/debug.adb
index b7c54a00066..ffe4adc790e 100644
--- a/gcc/ada/debug.adb
+++ b/gcc/ada/debug.adb
@@ -105,7 +105,7 @@ package body Debug is
    --  d.r  Disable reordering of components in record types
    --  d.s  Strict secondary stack management
    --  d.t  Disable static allocation of library level dispatch tables
-   --  d.u
+   --  d.u  Enable Unsigned_Base_Range aspect language extension
    --  d.v  Enforce SPARK elaboration rules in SPARK code
    --  d.w  Do not check for infinite loops
    --  d.x  No exception handlers
@@ -800,7 +800,8 @@ package body Debug is
    --       previous dynamic construction of tables. It is there as a possible
    --       work around if we run into trouble with the new implementation.
 
-   --  d.u
+   --  d.u  Enable the support for Unsigned_Base_Range aspect, attribute, and
+   --       pragma.
 
    --  d.v  This flag enforces the elaboration rules defined in the SPARK
    --       Reference Manual, chapter 7.7, to all SPARK code within a unit. As
diff --git a/gcc/ada/einfo-utils.adb b/gcc/ada/einfo-utils.adb
index 290ae331d37..b0acb25b40b 100644
--- a/gcc/ada/einfo-utils.adb
+++ b/gcc/ada/einfo-utils.adb
@@ -333,7 +333,8 @@ package body Einfo.Utils is
 
    function Is_Modular_Integer_Type             (Id : E) return B is
    begin
-      return Ekind (Id) in Modular_Integer_Kind;
+      return Ekind (Id) in Modular_Integer_Kind
+        and then not Has_Unsigned_Base_Range_Aspect (Base_Type (Id));
    end Is_Modular_Integer_Type;
 
    function Is_Named_Access_Type                (Id : E) return B is
@@ -393,7 +394,10 @@ package body Einfo.Utils is
 
    function Is_Signed_Integer_Type              (Id : E) return B is
    begin
-      return Ekind (Id) in Signed_Integer_Kind;
+      return Ekind (Id) in Signed_Integer_Kind
+        or else
+          (Ekind (Id) in Modular_Integer_Kind
+             and then Has_Unsigned_Base_Range_Aspect (Base_Type (Id)));
    end Is_Signed_Integer_Type;
 
    function Is_Subprogram                       (Id : E) return B is
diff --git a/gcc/ada/einfo.ads b/gcc/ada/einfo.ads
index b5d9c1cde66..b9548a78f84 100644
--- a/gcc/ada/einfo.ads
+++ b/gcc/ada/einfo.ads
@@ -5757,6 +5757,7 @@ package Einfo is
    --    Non_Binary_Modulus                   (base type only)
    --    Has_Biased_Representation
    --    Has_Shift_Operator                   (base type only)
+   --    Has_Unsigned_Base_Range_Aspect       (base type only)
    --    No_Predicate_On_Actual
    --    No_Dynamic_Predicate_On_Actual
    --    Type_Low_Bound                       (synth)
diff --git a/gcc/ada/par-ch4.adb b/gcc/ada/par-ch4.adb
index f8ae9970c88..338be465513 100644
--- a/gcc/ada/par-ch4.adb
+++ b/gcc/ada/par-ch4.adb
@@ -485,7 +485,8 @@ package body Ch4 is
             --  Attribute Unsigned_Base_Range temporarily disabled
 
             if not Is_Attribute_Name (Attr_Name)
-              or else Attr_Name = Name_Unsigned_Base_Range
+              or else (Attr_Name = Name_Unsigned_Base_Range
+                         and then not Debug_Flag_Dot_U)
             then
                if Apostrophe_Should_Be_Semicolon then
                   Expr_Form := EF_Name;
diff --git a/gcc/ada/sem_ch13.adb b/gcc/ada/sem_ch13.adb
index 22fea0d0290..4bff79d16a9 100644
--- a/gcc/ada/sem_ch13.adb
+++ b/gcc/ada/sem_ch13.adb
@@ -3590,6 +3590,7 @@ package body Sem_Ch13 is
                             | Aspect_Effective_Reads
                             | Aspect_Effective_Writes
                             | Aspect_Preelaborable_Initialization
+                            | Aspect_Unsigned_Base_Range
             then
                Error_Msg_Name_1 := Nam;
 
@@ -3703,6 +3704,13 @@ package body Sem_Ch13 is
                   then
                      Delay_Required := False;
 
+                  --  For Unsigned_Base_Range aspect, do not delay becase we
+                  --  need to process it before any type or subtype derivation
+                  --  is analyzed.
+
+                  elsif A_Id in Aspect_Unsigned_Base_Range then
+                     Delay_Required := False;
+
                   --  All other cases are delayed
 
                   else
diff --git a/gcc/ada/sem_ch3.adb b/gcc/ada/sem_ch3.adb
index 9ca77089d1a..aa15166fa86 100644
--- a/gcc/ada/sem_ch3.adb
+++ b/gcc/ada/sem_ch3.adb
@@ -11287,7 +11287,13 @@ package body Sem_Ch3 is
       --  not. It is OK for the new bound we are creating, but not for
       --  the old one??? Still if it never happens, no problem.
 
-      Analyze_And_Resolve (Bound, Base_Type (Par_T));
+      --  This must be disabled on unsigned base range types because their
+      --  base type is a modular type, and their type is a signed integer
+      --  type.
+
+      if not Has_Unsigned_Base_Range_Aspect (Base_Type (Par_T)) then
+         Analyze_And_Resolve (Bound, Base_Type (Par_T));
+      end if;
 
       if Nkind (Bound) in N_Integer_Literal | N_Real_Literal then
          New_Bound := New_Copy (Bound);
diff --git a/gcc/ada/sem_prag.adb b/gcc/ada/sem_prag.adb
index 59c1976dbe9..8d430516c04 100644
--- a/gcc/ada/sem_prag.adb
+++ b/gcc/ada/sem_prag.adb
@@ -12690,7 +12690,8 @@ package body Sem_Prag is
       --  Pragma Unsigned_Base_Range temporarily disabled
 
       if not Is_Pragma_Name (Pname)
-        or else Pname = Name_Unsigned_Base_Range
+        or else (Pname = Name_Unsigned_Base_Range
+                  and then not Debug_Flag_Dot_U)
       then
          declare
             Msg_Issued : Boolean := False;
@@ -28154,12 +28155,23 @@ package body Sem_Prag is
             then
                Error_Pragma_Arg
                  ("cannot apply pragma %",
-                  "\& is not a signed integer type",
-                  Arg1);
+                  "\& is not a signed integer type", Arg1);
 
             elsif Is_Derived_Type (E) then
                Error_Pragma_Arg
                  ("pragma % cannot apply to derived type", Arg1);
+
+            elsif Is_Generic_Type (E) then
+               Error_Pragma_Arg
+                 ("pragma % cannot apply to formal type", Arg1);
+
+            elsif Present (Expr)
+              and then Is_False (Expr_Value (Expr))
+              and then Ekind (Base_Type (E)) = E_Modular_Integer_Type
+              and then Has_Unsigned_Base_Range_Aspect (Base_Type (E))
+            then
+               Error_Pragma_Arg
+                 ("pragma % can only confirm previous True value", Arg1);
             end if;
 
             Check_First_Subtype (Arg1);
@@ -28167,17 +28179,19 @@ package body Sem_Prag is
             --  Create the new unsigned integer base type entity, and apply
             --  the constraint to create the first subtype of E.
 
-            Unsigned_Base_Range_Type_Declaration (E,
-              Def => Type_Definition (Parent (E)));
+            if No (Expr) or else Is_True (Expr_Value (Expr)) then
+               Unsigned_Base_Range_Type_Declaration (E,
+                 Def => Type_Definition (Parent (E)));
 
-            Set_Direct_Primitive_Operations (Base_Type (E), New_Elmt_List);
-            Set_Direct_Primitive_Operations (E,
-              Direct_Primitive_Operations (Base_Type (E)));
-            Ensure_Freeze_Node (Base_Type (E));
-            Set_First_Subtype_Link (Freeze_Node (Base_Type (E)), E);
-            Set_Has_Delayed_Freeze (E);
+               Set_Direct_Primitive_Operations (Base_Type (E), New_Elmt_List);
+               Set_Direct_Primitive_Operations (E,
+                 Direct_Primitive_Operations (Base_Type (E)));
+               Ensure_Freeze_Node (Base_Type (E));
+               Set_First_Subtype_Link (Freeze_Node (Base_Type (E)), E);
+               Set_Has_Delayed_Freeze (E);
 
-            Set_Has_Unsigned_Base_Range_Aspect (Base_Type (E));
+               Set_Has_Unsigned_Base_Range_Aspect (Base_Type (E));
+            end if;
          end Unsigned_Base_Range;
 
          ----------------
-- 
2.51.0

Reply via email to