checks.adb (Apply_Float_Conversion_Check): If the expression to be converted is a...
authorEd Schonberg <schonberg@adacore.com>
Fri, 1 Aug 2008 09:02:44 +0000 (11:02 +0200)
committerArnaud Charlet <charlet@gcc.gnu.org>
Fri, 1 Aug 2008 09:02:44 +0000 (11:02 +0200)
2008-08-01  Ed Schonberg  <schonberg@adacore.com>

* checks.adb (Apply_Float_Conversion_Check): If the expression to be
converted is a real literal and the target type has static bounds,
perform the conversion exactly to prevent floating-point anomalies on
some targets.

From-SVN: r138486

gcc/ada/checks.adb

index 6eb7ebbbbc3f27e185c6a6203bec90a0a5c7b125..f55bd7cec75d9f6fa9be5282c236e41c3c8f81f0 100644 (file)
@@ -1633,11 +1633,36 @@ package body Checks is
          end;
       end if;
 
-      --  Get the bounds of the target type
+      --  Get the (static) bounds of the target type
 
       Ifirst := Expr_Value (LB);
       Ilast  := Expr_Value (HB);
 
+      --  A simple optimization: if the expression is a universal literal,
+      --  we can do the comparison with the bounds and the conversion to
+      --  an integer type statically. The range checks are unchanged.
+
+      if Nkind (Ck_Node) = N_Real_Literal
+        and then Etype (Ck_Node) = Universal_Real
+        and then Is_Integer_Type (Target_Typ)
+        and then Nkind (Parent (Ck_Node)) = N_Type_Conversion
+      then
+         declare
+            Int_Val : constant Uint := UR_To_Uint (Realval (Ck_Node));
+
+         begin
+            if Int_Val <= Ilast and then Int_Val >= Ifirst then
+
+               --  Conversion is safe.
+
+               Rewrite (Parent (Ck_Node),
+                 Make_Integer_Literal (Loc, UI_To_Int (Int_Val)));
+               Analyze_And_Resolve (Parent (Ck_Node), Target_Typ);
+               return;
+            end if;
+         end;
+      end if;
+
       --  Check against lower bound
 
       if Truncate and then Ifirst > 0 then