This fixes an old issue involving the Enum_Val attribute: it does not
always raise a Constraint_Error exception when the specified value is
not valid for the enumeration type (instead a modulo computation is
applied to the value).

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

2019-07-22  Eric Botcazou  <ebotca...@adacore.com>

gcc/ada/

        * exp_attr.adb (Expand_N_Attribute_Reference)
        <Attribute_Enum_Val>: Set No_Truncation on the
        N_Unchecked_Type_Conversion built around the argument passed to
        the attribute.

gcc/testsuite/

        * gnat.dg/enum_val1.adb: New testcase.
--- gcc/ada/exp_attr.adb
+++ gcc/ada/exp_attr.adb
@@ -3282,6 +3282,13 @@ package body Exp_Attr is
 
          Expr := Unchecked_Convert_To (Ptyp, First (Exprs));
 
+         --  Ensure that the expression is not truncated since the "bad" bits
+         --  are desired.
+
+         if Nkind (Expr) = N_Unchecked_Type_Conversion then
+            Set_No_Truncation (Expr);
+         end if;
+
          Insert_Action (N,
            Make_Raise_Constraint_Error (Loc,
              Condition =>

--- /dev/null
new file mode 100644
+++ gcc/testsuite/gnat.dg/enum_val1.adb
@@ -0,0 +1,22 @@
+with Ada.Text_IO; use Ada.Text_IO;
+
+procedure Enum_Val1 is
+   type Enum is (Two, Four);
+   for Enum use (2, 4);
+
+   Count : Natural := 0;
+
+begin
+   for I in 10 .. 11 loop
+      begin
+         Put (Integer'Image (I) & ": ");
+         Put_Line (Enum'Image (Enum'Enum_Val (I)));
+      exception
+         when Constraint_Error =>
+            Count := Count + 1;
+      end;
+   end loop;
+   if Count /= 2 then
+      raise Program_Error;
+   end if;
+end;

Reply via email to