This patch allows the prefix of the attribute Enum_Rep to be an
attribute referece (such as Enum_Type'First). A recent patch had
restricted the prefix to be an object of a discrete type, which is
incompatible with orevious usage.

Tested on x86_64-pc-linux-gnu, committed on trunk

2019-07-01  Ed Schonberg  <schonb...@adacore.com>

gcc/ada/

        * sem_attr.adb (Analyze_Attribute, case Enum_Rep): Allow prefix
        of attribute to be an attribute reference of a discrete type.

gcc/testsuite/

        * gnat.dg/enum_rep.adb, gnat.dg/enum_rep.ads: New testcase.
--- gcc/ada/sem_attr.adb
+++ gcc/ada/sem_attr.adb
@@ -3833,14 +3833,16 @@ package body Sem_Attr is
             Check_Discrete_Type;
             Resolve (E1, P_Base_Type);
 
-         --  X'Enum_Rep case. X must be an object or enumeration literal, and
-         --  it must be of a discrete type.
+         --  X'Enum_Rep case. X must be an object or enumeration literal
+         --  (including an attribute reference), and it must be of a
+         --  discrete type.
 
          elsif not
            ((Is_Object_Reference (P)
                or else
                  (Is_Entity_Name (P)
-                    and then Ekind (Entity (P)) = E_Enumeration_Literal))
+                    and then Ekind (Entity (P)) = E_Enumeration_Literal)
+               or else Nkind (P) = N_Attribute_Reference)
              and then Is_Discrete_Type (Etype (P)))
          then
             Error_Attr_P ("prefix of % attribute must be discrete object");

--- /dev/null
new file mode 100644
+++ gcc/testsuite/gnat.dg/enum_rep.adb
@@ -0,0 +1,5 @@
+--  { dg-do compile }
+
+package body Enum_Rep is
+   procedure Foo is null;
+end;

--- /dev/null
new file mode 100644
+++ gcc/testsuite/gnat.dg/enum_rep.ads
@@ -0,0 +1,22 @@
+with Interfaces;
+
+package Enum_Rep is
+
+   type My_Type is range 00 .. 100;
+
+   subtype My_Subtype2 is Interfaces.Unsigned_32
+        range My_Type'First'Enum_Rep .. My_Type'Last'Enum_Rep;
+
+   My_Type_First : constant My_Type :=  My_Type'First;
+   My_Type_Last : constant My_Type :=  My_Type'Last;
+
+   subtype My_Subtype is Interfaces.Unsigned_32
+         range My_Type_First'Enum_Rep .. My_Type_Last'Enum_Rep;
+
+   subtype My_Subtype1 is Interfaces.Unsigned_32
+        range My_Type'Enum_Rep (My_Type'First) ..
+               My_Type'Enum_Rep (MY_Type'Last);
+
+   procedure Foo;
+
+end;

Reply via email to