diff mbox

[Ada] Case statements over predicated subtypes

Message ID 20120515093810.GA851@adacore.com
State New
Headers show

Commit Message

Arnaud Charlet May 15, 2012, 9:38 a.m. UTC
In Ada 2012, if a subtype has a static predicate the set of its possible values
is known statically and those are the alternatives that must be covered in in
case statement. If the subtype has dynamic predicates, the alternatives must
cover all values of the base type.

Compiling nonstaticcase.adb in Ada 2012 mode must yield:

   nonstaticcase.adb:7:04: missing case values: -16#8000_0000# .. 0
   nonstaticcase.adb:7:04: missing case values: 11 .. 16#7FFF_FFFF#
   nonstaticcase.adb:7:09: bounds of "rr" are not static,
         alternatives must cover base type

---
procedure nonstaticcase (rmin : integer) is
   subtype r is integer range 1 .. 10
     with Dynamic_Predicate => r >= rmin;
   rr : r;
begin
   rr := rmin + 1;
   case rr is
      when 1 .. 10 => null;
   end case;
end;

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

2012-05-15  Ed Schonberg  <schonberg@adacore.com>

	* sem_case.adb (Analyze_Choices): If the subtype of the
	expression has a non-static predicate, the case alternatives
	must cover the base type.
diff mbox

Patch

Index: sem_case.adb
===================================================================
--- sem_case.adb	(revision 187501)
+++ sem_case.adb	(working copy)
@@ -803,8 +803,18 @@ 
          --  bounds of its base type to determine the values covered by the
          --  discrete choices.
 
+         --  In Ada 2012, if the subtype has a non-static predicate the full
+         --  range of the base type must be covered as well.
+
          if Is_OK_Static_Subtype (Subtyp) then
-            Bounds_Type := Subtyp;
+            if not Has_Predicates (Subtyp)
+              or else Present (Static_Predicate (Subtyp))
+            then
+               Bounds_Type := Subtyp;
+            else
+               Bounds_Type := Choice_Type;
+            end if;
+
          else
             Bounds_Type := Choice_Type;
          end if;