The compiler confuses itself because it generates a range check in Float
whose upper bound is 2 ** 128, but this number is larger than the largest
number representable in Float so it triggers an error when converted to
Float as part of the check.

The fix is to saturate the upper bound of the check to that of Float.

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

gcc/ada/

        * checks.adb (Apply_Float_Conversion_Check): Saturate the bounds
        of the check to those of the base type of the expression.
diff --git a/gcc/ada/checks.adb b/gcc/ada/checks.adb
--- a/gcc/ada/checks.adb
+++ b/gcc/ada/checks.adb
@@ -2149,6 +2149,15 @@ package body Checks is
          Lo_OK := (Lo >= UR_From_Uint (Ifirst));
       end if;
 
+      --  Saturate the lower bound to that of the expression's type, because
+      --  we do not want to create an out-of-range value but we still need to
+      --  do a comparison to catch NaNs.
+
+      if Lo < Expr_Value_R (Type_Low_Bound (Expr_Type)) then
+         Lo := Expr_Value_R (Type_Low_Bound (Expr_Type));
+         Lo_OK := True;
+      end if;
+
       if Lo_OK then
 
          --  Lo_Chk := (X >= Lo)
@@ -2183,6 +2192,15 @@ package body Checks is
          Hi_OK := (Hi <= UR_From_Uint (Ilast));
       end if;
 
+      --  Saturate the higher bound to that of the expression's type, because
+      --  we do not want to create an out-of-range value but we still need to
+      --  do a comparison to catch NaNs.
+
+      if Hi > Expr_Value_R (Type_High_Bound (Expr_Type)) then
+         Hi := Expr_Value_R (Type_High_Bound (Expr_Type));
+         Hi_OK := True;
+      end if;
+
       if Hi_OK then
 
          --  Hi_Chk := (X <= Hi)


Reply via email to