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

If the compiler detects a floating division by zero,
it was unconditionally issuing a warning and raising a
constraint_error. This is wrong behavior for the case of an
unconstained floating point type. This patch corrects that
behavior as shown by the following test program

     1. procedure TESTfdz is
     2.
     3.    type REAL_T is record
     4.       VALUE : FLOAT;
     5.    end record;
     6.
     7.    function "/"  (LEFT, RIGHT : in REAL_T) return REAL_T is
     8.    begin
     9.       return (VALUE => LEFT.VALUE / RIGHT.VALUE);
    10.    end "/";
    11.
    12.    X : REAL_T := (VALUE => 1.0);
    13.    Y : FLOAT := 1.0;
    14.
    15.    type CF is digits 6 range 0.0 .. 1.0;
    16.    Z : CF := 1.0;
    17.
    18. begin
    19.    X := X / (VALUE => 0.0);
    20.    Y := Y / 0.0;
                    |
        >>> warning: float division by zero, may generate
            +/- infinity

    21.    Z := Z / 0.0;
                    |
        >>> warning: division by zero, "Constraint_Error"
            will be raised at run time

    22. end;

2011-10-06  Robert Dewar  <de...@adacore.com>

        * sem_res.adb (Resolve_Arithmetic_Op): Fix bad warning for
        floating divide by zero.

Index: sem_res.adb
===================================================================
--- sem_res.adb (revision 179628)
+++ sem_res.adb (working copy)
@@ -64,6 +64,7 @@
 with Sem_Eval; use Sem_Eval;
 with Sem_Intr; use Sem_Intr;
 with Sem_Util; use Sem_Util;
+with Targparm; use Targparm;
 with Sem_Type; use Sem_Type;
 with Sem_Warn; use Sem_Warn;
 with Sinfo;    use Sinfo;
@@ -4874,14 +4875,34 @@
                            (Is_Real_Type (Etype (Rop))
                              and then Expr_Value_R (Rop) = Ureal_0))
             then
-               --  Specialize the warning message according to the operation
+               --  Specialize the warning message according to the operation.
+               --  The following warnings are for the case
 
                case Nkind (N) is
                   when N_Op_Divide =>
-                     Apply_Compile_Time_Constraint_Error
-                       (N, "division by zero?", CE_Divide_By_Zero,
-                        Loc => Sloc (Right_Opnd (N)));
 
+                     --  For division, we have two cases, for float division
+                     --  of an unconstrained float type, on a machine where
+                     --  Machine_Overflows is false, we don't get an exception
+                     --  at run-time, but rather an infinity or Nan. The Nan
+                     --  case is pretty obscure, so just warn about infinities.
+
+                     if Is_Floating_Point_Type (Typ)
+                       and then not Is_Constrained (Typ)
+                       and then not Machine_Overflows_On_Target
+                     then
+                        Error_Msg_N
+                          ("float division by zero, " &
+                           "may generate '+'/'- infinity?", Right_Opnd (N));
+
+                        --  For all other cases, we get a Constraint_Error
+
+                     else
+                        Apply_Compile_Time_Constraint_Error
+                          (N, "division by zero?", CE_Divide_By_Zero,
+                           Loc => Sloc (Right_Opnd (N)));
+                     end if;
+
                   when N_Op_Rem =>
                      Apply_Compile_Time_Constraint_Error
                        (N, "rem with zero divisor?", CE_Divide_By_Zero,

Reply via email to