[Ada] A static predicate can be specified by a Case expression.
Arnaud Charlet
charlet@adacore.com
Wed Jul 16 14:47:00 GMT 2014
This patch completes the implementation of Ada 2012 static predicates, by
adding support for case expressions that can be transformed into a statically
evaluable expression on values of the subtype. Compiling:
gcc -c -gnata test_predicate.adb
must yield:
test_predicate.adb:11:20:
warning: static expression fails static predicate check on "Weekend"
test_predicate.adb:19:25:
warning: static expression fails static predicate check on "French_School"
---
with Text_IO; use Text_IO;
procedure Test_Predicate is
type Days is (Sun, Mon, Tue, Wed, Thu, Fri, Sat);
subtype Weekend is Days with Static_Predicate =>
(case Weekend is
when Sat | Sun => True,
when Mon .. Fri => False);
W : Weekend := Tue;
subtype French_School is Days with Static_Predicate =>
(case French_School is
when Mon | Tue => True,
when Wed => False,
when Thu..Fri => True,
when Sat | Sun => False);
J : French_School := Wed;
begin
Put_Line (W'Img);
end Test_Predicate;
Tested on x86_64-pc-linux-gnu, committed on trunk
2014-07-16 Ed Schonberg <schonberg@adacore.com>
* exp_ch4.adb (Expand_N_Case_Expression): Do not expand case
expression if it is the specification of a subtype predicate:
it will be expanded when the return statement is analyzed, or
when a static predicate is transformed into a static expression
for evaluation by the front-end.
* sem_ch13.adb (Get_RList): If the expression for a static
predicate is a case expression, extract the alternatives of the
branches with a True value to create the required statically
evaluable expression.
-------------- next part --------------
Index: exp_ch4.adb
===================================================================
--- exp_ch4.adb (revision 212648)
+++ exp_ch4.adb (working copy)
@@ -4927,6 +4927,16 @@
return;
end if;
+ -- If the case expression is a predicate specification, do not
+ -- expand, because it will be converted to the proper predicate
+ -- form when building the predicate function.
+
+ if Ekind_In (Current_Scope, E_Function, E_Procedure)
+ and then Is_Predicate_Function (Current_Scope)
+ then
+ return;
+ end if;
+
-- We expand
-- case X is when A => AX, when B => BX ...
Index: sem_ch13.adb
===================================================================
--- sem_ch13.adb (revision 212656)
+++ sem_ch13.adb (working copy)
@@ -7584,12 +7584,47 @@
when N_Qualified_Expression =>
return Get_RList (Expression (Exp));
+ when N_Case_Expression =>
+ declare
+ Alt : Node_Id;
+ Choices : List_Id;
+ Dep : Node_Id;
+
+ begin
+ if not Is_Entity_Name (Expression (Expr))
+ or else Etype (Expression (Expr)) /= Typ
+ then
+ Error_Msg_N
+ ("expression must denaote subtype", Expression (Expr));
+ return False_Range;
+ end if;
+
+ -- Collect discrete choices in all True alternatives
+
+ Choices := New_List;
+ Alt := First (Alternatives (Exp));
+ while Present (Alt) loop
+ Dep := Expression (Alt);
+
+ if not Is_Static_Expression (Dep) then
+ raise Non_Static;
+
+ elsif Is_True (Expr_Value (Dep)) then
+ Append_List_To (Choices,
+ New_Copy_List (Discrete_Choices (Alt)));
+ end if;
+
+ Next (Alt);
+ end loop;
+
+ return Membership_Entries (First (Choices));
+ end;
+
-- Expression with actions: if no actions, dig out expression
when N_Expression_With_Actions =>
if Is_Empty_List (Actions (Exp)) then
return Get_RList (Expression (Exp));
-
else
raise Non_Static;
end if;
More information about the Gcc-patches
mailing list