summaryrefslogtreecommitdiff
path: root/gcc/ada/checks.adb
diff options
context:
space:
mode:
authorcharlet <charlet@138bc75d-0d04-0410-961f-82ee72b054a4>2008-08-01 09:02:44 +0000
committercharlet <charlet@138bc75d-0d04-0410-961f-82ee72b054a4>2008-08-01 09:02:44 +0000
commit7d86aa98343399b59afd325c6224b76b63d52c1c (patch)
treed764922d7874c29d0afee9da316ce2c0ab88b390 /gcc/ada/checks.adb
parentbff9d49b8620914119bb0dde6f599552685db017 (diff)
downloadgcc-7d86aa98343399b59afd325c6224b76b63d52c1c.tar.gz
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. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@138486 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/ada/checks.adb')
-rw-r--r--gcc/ada/checks.adb27
1 files changed, 26 insertions, 1 deletions
diff --git a/gcc/ada/checks.adb b/gcc/ada/checks.adb
index 6eb7ebbbbc3..f55bd7cec75 100644
--- a/gcc/ada/checks.adb
+++ b/gcc/ada/checks.adb
@@ -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