[Ada] Further fixes to MINIMIZED overflow checking mode

Message ID 20121003083034.GA17746@adacore.com
State New
Headers show

Commit Message

Arnaud Charlet Oct. 3, 2012, 8:30 a.m.
This patch has three components. First we set SUPPRESSED mode as the
default for -gnatg mode (including the run-time). This has no effect
right now, but avoids hidden problems that may appear if in future
we make overflow checking the default behavior.

Second, in some obscure cases, the overflow checking code was
generating bogus warnings for redundant type conversions from
generated overflow checking code in MINIMIZED/ELIMINATED mode.
No simple test has been found for this, and the conditions
are quite obscure (and not well understood!) but the patch
decisively eliminates such bogus warnings.

Finally, we properly handle the case where the result is
converted to a larger type. The following test program:

     1. with Text_IO; use Text_IO;
     2. procedure convov is
     3.    function a (x : integer)
     4.      return Long_Long_Integer
     5.    is
     6.    begin
     7.       return Long_Long_Integer (x * x);
     8.    end;
     9. begin
    10.    Put_Line (a (Integer'Last)'Img);
    11. end;

when run in -gnato2 or -gnato3 mode, compiles quietly
and outputs a single line:


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

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

	* checks.adb (Minimize_Eliminate_Overflow_Checks): Properly
	handle case of top level expression within type conversion
	* gnat1drv.adb (Adjust_Global_Switches): Set SUPPRESSED as
	default for overflow checking for -gnatg mode (includes run-time).
	* sem_res.adb (Resolve_Type_Conversion): Avoid bogus warnings
	about redundant conversions from MINIMIZED/EXTENDED mode checking


Index: checks.adb
--- checks.adb	(revision 192027)
+++ checks.adb	(working copy)
@@ -7404,6 +7404,16 @@ 
       elsif Top_Level
         and then not (Bignum_Operands or Long_Long_Integer_Operands)
+        --  One further refinement. If we are at the top level, but our parent
+        --  is a type conversion, then go into bignum or long long integer node
+        --  since the result will be converted to that type directly without
+        --  going through the result type, and we may avoid an overflow. This
+        --  is the case for example of Long_Long_Integer (A ** 4), where A is
+        --  of type Integer, and the result A ** 4 fits in Long_Long_Integer
+        --  but does not fit in Integer.
+        and then Nkind (Parent (N)) /= N_Type_Conversion
          --  Here we will keep the original types, but we do need an overflow
          --  check, so we will set Do_Overflow_Check to True (actually it is
@@ -7561,12 +7571,6 @@ 
       if Nkind (N) = N_Op_Expon and then Etype (Right_Opnd (N)) = LLIB then
          Convert_To_And_Rewrite (Standard_Natural, Right_Opnd (N));
-         --  Now Long_Long_Integer_Operands may have to be reset if that was
-         --  the only long long integer operand, i.e. we now have long long
-         --  integer operands only if the left operand is long long integer.
-         Long_Long_Integer_Operands := Etype (Left_Opnd (N)) = LLIB;
       end if;
       --  Here we will do the operation in Long_Long_Integer. We do this even
Index: sem_res.adb
--- sem_res.adb	(revision 192025)
+++ sem_res.adb	(working copy)
@@ -9624,6 +9624,13 @@ 
+            --  Never warn on conversion to Long_Long_Integer'Base since
+            --  that is most likely an artifact of the extended overflow
+            --  checking and comes from complex expanded code.
+            elsif Orig_T = Base_Type (Standard_Long_Long_Integer) then
+               null;
             --  Here we give the redundant conversion warning. If it is an
             --  entity, give the name of the entity in the message. If not,
             --  just mention the expression.
Index: gnat1drv.adb
--- gnat1drv.adb	(revision 192025)
+++ gnat1drv.adb	(working copy)
@@ -334,6 +334,12 @@ 
       if Opt.Suppress_Options.Overflow_Checks_General /= Not_Set then
+      --  By default suppress overflow checks in -gnatg mode
+      elsif GNAT_Mode then
+         Suppress_Options.Overflow_Checks_General    := Suppressed;
+         Suppress_Options.Overflow_Checks_Assertions := Suppressed;
       --  If we have backend divide and overflow checks, then by default
       --  overflow checks are minimized, which is a reasonable setting.