GNAT crashes when building static predicate functions out of a case
expression that contain an "others" clause. This is because it attempts
to call Is_OK_Static_Expression() on the N_Others_Choice of the case
expression when trying to figure out whether the case is exhaustive or
not.
Fixing requires two changes:
- Ensuring that choice values built out of `others` clauses have their
Is_Static_Expression flag set.
- Checking if N is an N_Others_Choice in Membership_Entry and if it is
returning the list of ranges that it corresponds to.
Tested on x86_64-pc-linux-gnu, committed on trunk
gcc/ada/
* sem_case.adb (Build_Choice): Set Is_Static_Expression flag.
(Lit_Of): Update specification to mention Is_Static_Expression
flag.
* sem_ch13.adb (Membership_Entry): Check for N_Others_Choice.
diff --git a/gcc/ada/sem_case.adb b/gcc/ada/sem_case.adb
--- a/gcc/ada/sem_case.adb
+++ b/gcc/ada/sem_case.adb
@@ -998,7 +998,8 @@ package body Sem_Case is
function Lit_Of (Value : Uint) return Node_Id;
-- Returns the Node_Id for the enumeration literal corresponding to the
- -- position given by Value within the enumeration type Choice_Type.
+ -- position given by Value within the enumeration type Choice_Type. The
+ -- returned value has its Is_Static_Expression flag set to true.
------------------
-- Build_Choice --
@@ -1016,6 +1017,7 @@ package body Sem_Case is
if Is_Integer_Type (Choice_Type) then
Lit_Node := Make_Integer_Literal (Loc, Value1);
Set_Etype (Lit_Node, Choice_Type);
+ Set_Is_Static_Expression (Lit_Node);
else
Lit_Node := Lit_Of (Value1);
end if;
@@ -1028,8 +1030,10 @@ package body Sem_Case is
if Is_Integer_Type (Choice_Type) then
Lo := Make_Integer_Literal (Loc, Value1);
Set_Etype (Lo, Choice_Type);
+ Set_Is_Static_Expression (Lo);
Hi := Make_Integer_Literal (Loc, Value2);
Set_Etype (Hi, Choice_Type);
+ Set_Is_Static_Expression (Hi);
Lit_Node :=
Make_Range (Loc,
Low_Bound => Lo,
diff --git a/gcc/ada/sem_ch13.adb b/gcc/ada/sem_ch13.adb
--- a/gcc/ada/sem_ch13.adb
+++ b/gcc/ada/sem_ch13.adb
@@ -9112,6 +9112,25 @@ package body Sem_Ch13 is
return RList'(1 => REnt'(SLo, SHi));
end if;
+ -- Others case
+
+ elsif Nkind (N) = N_Others_Choice then
+ declare
+ Choices : constant List_Id := Others_Discrete_Choices (N);
+ Choice : Node_Id;
+ Range_List : RList (1 .. List_Length (Choices));
+
+ begin
+ Choice := First (Choices);
+
+ for J in Range_List'Range loop
+ Range_List (J) := REnt'(Lo_Val (Choice), Hi_Val (Choice));
+ Next (Choice);
+ end loop;
+
+ return Range_List;
+ end;
+
-- Static expression case
elsif Is_OK_Static_Expression (N) then