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;