diff options
author | charlet <charlet@138bc75d-0d04-0410-961f-82ee72b054a4> | 2008-08-01 09:02:44 +0000 |
---|---|---|
committer | charlet <charlet@138bc75d-0d04-0410-961f-82ee72b054a4> | 2008-08-01 09:02:44 +0000 |
commit | 7d86aa98343399b59afd325c6224b76b63d52c1c (patch) | |
tree | d764922d7874c29d0afee9da316ce2c0ab88b390 /gcc/ada/checks.adb | |
parent | bff9d49b8620914119bb0dde6f599552685db017 (diff) | |
download | gcc-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.adb | 27 |
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 |