Patchwork [Ada] Remaining fixes for -gnato3 (eliminated mode overflow checks)

login
register
mail settings
Submitter Arnaud Charlet
Date Oct. 4, 2012, 9:12 a.m.
Message ID <20121004091229.GA2337@adacore.com>
Download mbox | patch
Permalink /patch/189070/
State New
Headers show

Comments

Arnaud Charlet - Oct. 4, 2012, 9:12 a.m.
This patch corrects a couple of errors in the handling of ELIMINATED mode
overflow checking. With this patch, the entire test suite passes with
-gnato3 mode forced on (there are some differences in output, but all
are expected).

The following three tests now work correctly

The following compiles quietly with -gnato3 and outputs TRUE

     1. with Text_IO; use Text_IO;
     2. procedure InGNATo3 is
     3.    function K (X, Z : Integer) return Boolean is
     4.    begin
     5.       return X in 1 .. Z ** 10;
     6.    end;
     7. begin
     8.    Put_Line (K (1, Integer'Last)'Img);
     9. end;

The following test compiles with the messages shown, regardless
of -gnato mode, and in particular this is now the -gnato3 output.

     1. procedure whynonso3 (a : integer) is
     2.    x : constant := 1 + a ** 10;
                           1   2
        >>> non-static expression used in number declaration
        >>> "a" is not static constant or named number (RM 4.9(5))

     3. begin
     4.    null;
     5. end;

The following test compiles quietly in -gnato3 mode

     1. procedure BadAleno3 is
     2.    type Arr is array (Positive range <>) of Integer;
     3.    N : Integer := 0;
     4.
     5.    type ARR_DEF (D3 : INTEGER) is   record
     6.       C1 : Arr (N .. D3);
     7.    end record;
     8.
     9.    A : Arr := (1, 2);
    10.    X : constant ARR_DEF := (1, A );
    11. begin
    12.    null;
    13. end BadAleno3;

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

2012-10-04  Robert Dewar  <dewar@adacore.com>

	* exp_ch4.adb (Expand_Compare_Minimize_Eliminate_Overflow):
	Deal with case where we get a bignum operand and cannot do a
	range analysis.
	* sem_eval.adb (Why_Not_Static): Deal with bignum operands

Patch

Index: exp_ch4.adb
===================================================================
--- exp_ch4.adb	(revision 192070)
+++ exp_ch4.adb	(working copy)
@@ -2325,9 +2325,12 @@ 
       Minimize_Eliminate_Overflow_Checks
         (Right_Opnd (N), Rlo, Rhi, Top_Level => False);
 
-      --  See if the range information decides the result of the comparison
+      --  See if the range information decides the result of the comparison.
+      --  We can only do this if we in fact have full range information (which
+      --  won't be the case if either operand is bignum at this stage).
 
-      case N_Op_Compare (Nkind (N)) is
+      if Llo /= No_Uint and then Rlo /= No_Uint then
+         case N_Op_Compare (Nkind (N)) is
          when N_Op_Eq =>
             if Llo = Lhi and then Rlo = Rhi and then Llo = Rlo then
                Set_True;
@@ -2369,12 +2372,13 @@ 
             elsif Llo > Rhi or else Lhi < Rlo then
                Set_True;
             end if;
-      end case;
+         end case;
 
-      --  All done if we did the rewrite
+         --  All done if we did the rewrite
 
-      if Nkind (N) not in N_Op_Compare then
-         return;
+         if Nkind (N) not in N_Op_Compare then
+            return;
+         end if;
       end if;
 
       --  Otherwise, time to do the comparison
Index: sem_eval.adb
===================================================================
--- sem_eval.adb	(revision 192070)
+++ sem_eval.adb	(working copy)
@@ -37,6 +37,7 @@ 
 with Nmake;    use Nmake;
 with Nlists;   use Nlists;
 with Opt;      use Opt;
+with Rtsfind;  use Rtsfind;
 with Sem;      use Sem;
 with Sem_Aux;  use Sem_Aux;
 with Sem_Cat;  use Sem_Cat;
@@ -5419,10 +5420,12 @@ 
             return;
          end if;
 
-         --  Type must be scalar or string type
+         --  Type must be scalar or string type (but allow Bignum, since this
+         --  is really a scalar type from our point of view in this diagnosis).
 
          if not Is_Scalar_Type (Typ)
            and then not Is_String_Type (Typ)
+           and then not Is_RTE (Typ, RE_Bignum)
          then
             Error_Msg_N
               ("static expression must have scalar or string type " &
@@ -5539,8 +5542,15 @@ 
 
          when N_Function_Call =>
             Why_Not_Static_List (Parameter_Associations (N));
-            Error_Msg_N ("non-static function call (RM 4.9(6,18))!", N);
 
+            --  Complain about non-static function call unless we have Bignum
+            --  which means that the underlying expression is really some
+            --  scalar arithmetic operation.
+
+            if not Is_RTE (Typ, RE_Bignum) then
+               Error_Msg_N ("non-static function call (RM 4.9(6,18))!", N);
+            end if;
+
          when N_Parameter_Association =>
             Why_Not_Static (Explicit_Actual_Parameter (N));