diff options
author | Arnaud Charlet <charlet@gcc.gnu.org> | 2015-01-07 10:52:50 +0100 |
---|---|---|
committer | Arnaud Charlet <charlet@gcc.gnu.org> | 2015-01-07 10:52:50 +0100 |
commit | c3831524bc0bf8d15bc95e26832a2a5e0752f9cc (patch) | |
tree | 24a17934b629bb46778ca5d90adbe1188eb86824 /gcc/ada/a-reatim.adb | |
parent | 1a9ee22281e0902c673d3c2e4cb5b83e07786569 (diff) | |
download | gcc-c3831524bc0bf8d15bc95e26832a2a5e0752f9cc.zip gcc-c3831524bc0bf8d15bc95e26832a2a5e0752f9cc.tar.gz gcc-c3831524bc0bf8d15bc95e26832a2a5e0752f9cc.tar.bz2 |
[multiple changes]
2015-01-07 Tristan Gingold <gingold@adacore.com>
* i-cpoint.adb (Copy_Terminated_Array): Use Copy_Array to
handle overlap.
2015-01-07 Eric Botcazou <ebotcazou@adacore.com>
* sem_ch3.adb (Analyze_Full_Type_Declaration): Do not
automatically set No_Strict_Aliasing on access types.
* fe.h (No_Strict_Aliasing_CP): Declare.
* gcc-interface/trans.c (gigi): Force flag_strict_aliasing to 0 if
No_Strict_Aliasing_CP is set.
2015-01-07 Johannes Kanig <kanig@adacore.com>
* sem_ch8.adb (Analyze_Subprogram_Renaming) do
not build function wrapper in gnatprove mode when the package
is externally axiomatized.
2015-01-07 Jose Ruiz <ruiz@adacore.com>
* a-reatim.adb (Time_Of): Reduce the number of spurious overflows in
intermediate computations when the parameters have different signs.
2015-01-07 Javier Miranda <miranda@adacore.com>
* exp_ch3.adb (Build_Init_Procedure): For derived types,
improve the code which takes care of identifying and moving to
the beginning of the init-proc the call to the init-proc of the
parent type.
From-SVN: r219287
Diffstat (limited to 'gcc/ada/a-reatim.adb')
-rw-r--r-- | gcc/ada/a-reatim.adb | 53 |
1 files changed, 52 insertions, 1 deletions
diff --git a/gcc/ada/a-reatim.adb b/gcc/ada/a-reatim.adb index f59d083..1a233c4 100644 --- a/gcc/ada/a-reatim.adb +++ b/gcc/ada/a-reatim.adb @@ -218,7 +218,58 @@ package body Ada.Real_Time is function Time_Of (SC : Seconds_Count; TS : Time_Span) return Time is begin - return Time (SC) + TS; + -- We want to return Time (SC) + TS. To avoid spurious overflows in + -- the intermediate result Time (SC) we take advantage of the different + -- signs in SC and TS (when that is the case). + + -- If signs of SC and TS are different then we avoid converting SC to + -- Time (as we do in the else part). The reason for that is that SC + -- converted to Time may overflow the range of Time, while the addition + -- of SC plus TS does not overflow (because of their different signs). + -- The approach is to add and remove the greatest value of time + -- (greatest absolute value) to both SC and TS. SC and TS have different + -- signs, so we add the positive constant to the negative value, and the + -- negative constant to the positive value, to prevent overflows. + + if (SC > 0 and then TS < 0.0) + or else (SC < 0 and then TS > 0.0) + then + declare + Closest_Boundary : constant Seconds_Count := + (if TS >= 0.0 then + Seconds_Count (Time_Span_Last - Time_Span (0.5)) + else + Seconds_Count (Time_Span_First + Time_Span (0.5))); + -- Value representing the integer part of the Time_Span boundary + -- closest to TS (its number of seconds). Truncate towards zero + -- to be sure that transforming this value back into Time cannot + -- overflow (when SC is equal to 0). The sign of Closest_Boundary + -- is always different from the sign of SC, hence avoiding + -- overflow in the expression Time (SC + Closest_Boundary) + -- which is part of the return statement. + + Dist_To_Boundary : constant Time_Span := + TS - Time_Span (Closest_Boundary); + -- Distance between TS and Closest_Boundary expressed in Time_Span + -- Both operands in the substraction have the same sign, hence + -- avoiding overflow. + + begin + -- Both operands in the inner addition have different signs, + -- hence avoiding overflow. The Time () conversion and the outer + -- addition can overflow only if SC + TC is not within Time'Range. + + return Time (SC + Closest_Boundary) + Dist_To_Boundary; + end; + + -- Both operands have the same sign, so we can convert SC into Time + -- right away; if this conversion overflows then the result of adding SC + -- and TS would overflow anyway (so we would just be detecting the + -- overflow a bit earlier). + + else + return Time (SC) + TS; + end if; end Time_Of; ----------------- |