diff mbox

[Ada] Constants are non-static if they fail a predicate check

Message ID 20140718100947.GA9588@adacore.com
State New
Headers show

Commit Message

Arnaud Charlet July 18, 2014, 10:09 a.m. UTC
If a constant is defined with a static expression, and the expression
statically fails a static predicate, then the constant is not considered
as being static, as shown by this updated example (see last few lines)

     1. package TestSP is
     2.    subtype F1 is Float with -- OK
     3.      Static_Predicate => F1 > 0.0 and 4.7 > F1;
     4.    subtype F2 is Float with -- ERROR
     5.      Static_Predicate => (F2 + 1.0) > 0.0 and 4.7 > F2;
                                  |
        >>> expression is not predicate-static (RM 4.3.2(16-22))

     6.    subtype F3 is Float with -- OK
     7.      Dynamic_Predicate => (F3 + 1.0) > 0.0 and 4.7 > F3;
     8.    subtype F4 is Float with -- OK
     9.      Predicate => (F4 + 1.0) > 0.0 and 4.7 > F4;
    10.
    11.    subtype S1 is String with -- OK
    12.      Static_Predicate => S1 > "ABC" and then "DEF" >= S1;
    13.    subtype S2 is String with -- ERROR
    14.      Static_Predicate => S2'First = 1 and then S2(1) = 'A';
                                 |
        >>> static predicate not allowed for non-scalar type "S2"

    15.    subtype S3 is String with -- OK
    16.      Dynamic_Predicate => S3'First = 1 and then S3(1) = 'A';
    17.    subtype S4 is String with -- OK
    18.      Predicate => S4'First = 1 and then S4(1) = 'A';
    19.
    20.    subtype I1 is Integer with -- OK
    21.      Static_Predicate => I1 > 0 and 4 > I1;
    22.    subtype I2 is Integer with -- ERROR
    23.      Static_Predicate => (I2 + 1) > 0 and 4 > I2;
                                  |
        >>> expression is not predicate-static (RM 4.3.2(16-22))

    24.    subtype I3 is Integer with -- OK
    25.      Dynamic_Predicate => (I3 + 1) > 0 and 4 > I3;
    26.    subtype I4 is Integer with -- OK
    27.      Predicate => (I4 + 1) > 0 and 4 > I4;
    28.    subtype I5 is Integer with -- ERROR (not caught before)
    29.      Static_Predicate => Boolean'(I5 > 0);
                                 |
        >>> expression is not predicate-static (RM 4.3.2(16-22))

    30.
    31.    XF1 : constant F1 := 10.0; -- WARN (not yet)
                                |
        >>> warning: real predicate not applied

    32.    XF2 : constant F1 := 3.0;  -- OK
                                |
        >>> warning: real predicate not applied

    33.    XF3 : constant := XF1;     -- ERROR (not caught yet)
    34.    XF4 : constant := XF2;     -- OK
    35.
    36.    XI1 : constant I1 := 10; -- WARN
                                |
        >>> warning: static expression fails predicate check on "I1"
        >>> warning: expression is no longer considered static

    37.    XI2 : constant I1 := 3;  -- OK
    38.    XI3 : constant := XI1;   -- ERROR
                             |
        >>> non-static expression used in number declaration
        >>> "XI1" is not a static constant (RM 4.9(5))

    39.    XI4 : constant := XI2;   -- OK
    40. end;

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

2014-07-18  Robert Dewar  <dewar@adacore.com>

	* sem_util.adb (Check_Expression_Against_Static_Predicate):
	Mark expression as non-static if it fails static predicate check,
	and issue additional warning.
diff mbox

Patch

Index: sem_util.adb
===================================================================
--- sem_util.adb	(revision 212804)
+++ sem_util.adb	(working copy)
@@ -1718,6 +1718,17 @@ 
          else
             Error_Msg_NE
               ("??static expression fails predicate check on &", Expr, Typ);
+
+            --  We now reset the static expression indication on the expression
+            --  since it is no longer static if it fails a predicate test. We
+            --  do not do this if the predicate was officially dynamic, since
+            --  dynamic predicates don't affect legality in this manner.
+
+            if not Has_Dynamic_Predicate_Aspect (Typ) then
+               Error_Msg_N
+                 ("\??expression is no longer considered static", Expr);
+               Set_Is_Static_Expression (Expr, False);
+            end if;
          end if;
       end if;
    end Check_Expression_Against_Static_Predicate;