Patchwork [Ada] Remove junk overflow check on MOD/REM/unary "+"

login
register
mail settings
Submitter Arnaud Charlet
Date Dec. 5, 2012, 10:30 a.m.
Message ID <20121205103013.GA4531@adacore.com>
Download mbox | patch
Permalink /patch/203821/
State New
Headers show

Comments

Arnaud Charlet - Dec. 5, 2012, 10:30 a.m.
This patch removes the setting of the overflow flag for MOD, REM,
and unary "+" operators, since overflow is not possible.

This does not have a functional effect for the compiler since
overflow is not possible anyway, but it did affect some other
tools (notably gnatprove, which had to do extra work dealing
with these junk flags).

The following program:

     1. procedure BadRemOverflow (X, Y : Integer) is
     2.    Z1 : Integer := X rem Y;
     3.    Z2 : Integer := X mod Y;
     4.    Z3 : Integer := +X;
     5. begin
     6.    null;
     7. end BadRemOverflow;

generates the following -gnatG output:

     procedure badremoverflow (x : integer; y : integer) is
        [constraint_error when
          y = 0
          "divide by zero"]
        z1 : integer := (if y = -1 then 0 else x rem y);
        [constraint_error when
          y = 0
          "divide by zero"]
        z2 : integer := (if y = -1 then 0 else x mod y);
        z3 : integer := +x;
     begin
        null;
        return;
     end badremoverflow;

Prior to this patch, the rem, mod and + operators were surrounded
with {} brackets indicating the presence of an overflow check.

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

2012-12-05  Robert Dewar  <dewar@adacore.com>

	* checks.ads, checks.adb (Activate_Overflow_Check): No effect for
	MOD/REM/unary +
	* exp_ch4.adb (Expand_N_Op_Mod): Remove call to set Do_Overflow_Check.

Patch

Index: checks.adb
===================================================================
--- checks.adb	(revision 194193)
+++ checks.adb	(working copy)
@@ -387,8 +387,10 @@ 
 
    procedure Activate_Overflow_Check (N : Node_Id) is
    begin
-      Set_Do_Overflow_Check (N, True);
-      Possible_Local_Raise (N, Standard_Constraint_Error);
+      if not Nkind_In (N, N_Op_Rem, N_Op_Mod, N_Op_Plus) then
+         Set_Do_Overflow_Check (N, True);
+         Possible_Local_Raise (N, Standard_Constraint_Error);
+      end if;
    end Activate_Overflow_Check;
 
    --------------------------
Index: checks.ads
===================================================================
--- checks.ads	(revision 194193)
+++ checks.ads	(working copy)
@@ -93,6 +93,8 @@ 
    --  Sets Do_Overflow_Check flag in node N, and handles possible local raise.
    --  Always call this routine rather than calling Set_Do_Overflow_Check to
    --  set an explicit value of True, to ensure handling the local raise case.
+   --  Note that this call has no effect for MOD, REM, and unary "+" for which
+   --  overflow is never possible in any case.
 
    procedure Activate_Range_Check (N : Node_Id);
    pragma Inline (Activate_Range_Check);
Index: exp_ch4.adb
===================================================================
--- exp_ch4.adb	(revision 194193)
+++ exp_ch4.adb	(working copy)
@@ -7910,7 +7910,6 @@ 
    procedure Expand_N_Op_Mod (N : Node_Id) is
       Loc   : constant Source_Ptr := Sloc (N);
       Typ   : constant Entity_Id  := Etype (N);
-      DOC   : constant Boolean    := Do_Overflow_Check (N);
       DDC   : constant Boolean    := Do_Division_Check (N);
 
       Left  : Node_Id;
@@ -7975,7 +7974,6 @@ 
 
          Set_Entity            (N, Standard_Entity (S_Op_Rem));
          Set_Etype             (N, Typ);
-         Set_Do_Overflow_Check (N, DOC);
          Set_Do_Division_Check (N, DDC);
          Expand_N_Op_Rem (N);
          Set_Analyzed (N);