From: Douglas B Rupp <r...@adacore.com> The Epochalypse of 2038 will require the use of 64-bit time_t and tv_sec (aka time in seconds from the Unix Epoch). The subprograms in Ada calendar are self contained but nevertheless will malfunction if a 64-bit integer type and calculations aren't used. Add 64-bit versions and mark the old ones with pragma Obsolescent.
gcc/ada/ChangeLog: * libgnat/a-calcon.adb (To_Ada_Time) (To_Duration) (To_Struct_Timespec) (To_Unix_Time): Mark as obsolescent. (To_Ada_Time_64) (To_Duration_64) (To_Struct_Timespec_64) (To_Unix_Time_64): New. * libgnat/a-calcon.ads (To_Ada_Time) (To_Duration) (To_Struct_Timespec) (To_Unix_Time): Mark as obsolescent. (To_Ada_Time_64) (To_Duration_64) (To_Struct_Timespec_64) (To_Unix_Time_64): New. * libgnat/a-calend.adb (To_Ada_Time) (To_Duration) (To_Struct_Timespec) (To_Unix_Time): Mark as obsolescent. (To_Ada_Time_64) (To_Duration_64) (To_Struct_Timespec_64) (To_Unix_Time_64): New. * libgnat/a-calend.ads (To_Ada_Time) (To_Duration) (To_Struct_Timespec) (To_Unix_Time): Mark as obsolescent. (To_Ada_Time_64) (To_Duration_64) (To_Struct_Timespec_64) (To_Unix_Time_64): New. Tested on x86_64-pc-linux-gnu, committed on master. --- gcc/ada/libgnat/a-calcon.adb | 54 ++++++++++++++++++++++++++++++++++ gcc/ada/libgnat/a-calcon.ads | 21 +++++++++++++ gcc/ada/libgnat/a-calend.adb | 57 +++++++++++++++++++++++++++++++----- gcc/ada/libgnat/a-calend.ads | 21 +++++++++++++ 4 files changed, 146 insertions(+), 7 deletions(-) diff --git a/gcc/ada/libgnat/a-calcon.adb b/gcc/ada/libgnat/a-calcon.adb index 8654d1ec569..5142456dfa7 100644 --- a/gcc/ada/libgnat/a-calcon.adb +++ b/gcc/ada/libgnat/a-calcon.adb @@ -43,6 +43,16 @@ package body Ada.Calendar.Conversions is return Conversion_Operations.To_Ada_Time (Val); end To_Ada_Time; + -------------------- + -- To_Ada_Time_64 -- + -------------------- + + function To_Ada_Time_64 (Unix_Time : long_long) return Time is + Val : constant Long_Long_Integer := Long_Long_Integer (Unix_Time); + begin + return Conversion_Operations.To_Ada_Time_64 (Val); + end To_Ada_Time_64; + ----------------- -- To_Ada_Time -- ----------------- @@ -83,6 +93,20 @@ package body Ada.Calendar.Conversions is return Conversion_Operations.To_Duration (Secs, Nano_Secs); end To_Duration; + -------------------- + -- To_Duration_64 -- + -------------------- + + function To_Duration_64 + (tv_sec : long_long; + tv_nsec : long) return Duration + is + Secs : constant Long_Long_Integer := Long_Long_Integer (tv_sec); + Nano_Secs : constant Long_Integer := Long_Integer (tv_nsec); + begin + return Conversion_Operations.To_Duration_64 (Secs, Nano_Secs); + end To_Duration_64; + ------------------------ -- To_Struct_Timespec -- ------------------------ @@ -102,6 +126,25 @@ package body Ada.Calendar.Conversions is tv_nsec := long (Nano_Secs); end To_Struct_Timespec; + --------------------------- + -- To_Struct_Timespec_64 -- + --------------------------- + + procedure To_Struct_Timespec_64 + (D : Duration; + tv_sec : out long_long; + tv_nsec : out long) + is + Secs : Long_Long_Integer; + Nano_Secs : Long_Integer; + + begin + Conversion_Operations.To_Struct_Timespec_64 (D, Secs, Nano_Secs); + + tv_sec := long_long (Secs); + tv_nsec := long (Nano_Secs); + end To_Struct_Timespec_64; + ------------------ -- To_Struct_Tm -- ------------------ @@ -145,6 +188,17 @@ package body Ada.Calendar.Conversions is return long (Val); end To_Unix_Time; + --------------------- + -- To_Unix_Time_64 -- + --------------------- + + function To_Unix_Time_64 (Ada_Time : Time) return long_long is + Val : constant Long_Long_Integer := + Conversion_Operations.To_Unix_Time_64 (Ada_Time); + begin + return long_long (Val); + end To_Unix_Time_64; + ----------------------- -- To_Unix_Nano_Time -- ----------------------- diff --git a/gcc/ada/libgnat/a-calcon.ads b/gcc/ada/libgnat/a-calcon.ads index 97df2a90175..a7be1f7f3fd 100644 --- a/gcc/ada/libgnat/a-calcon.ads +++ b/gcc/ada/libgnat/a-calcon.ads @@ -37,6 +37,10 @@ with Interfaces.C; package Ada.Calendar.Conversions is function To_Ada_Time (Unix_Time : Interfaces.C.long) return Time; + pragma Obsolescent (To_Ada_Time, "Retires in v26"); + -- Old version which will overflow at the 2038 Epochalypse + + function To_Ada_Time_64 (Unix_Time : Interfaces.C.long_long) return Time; -- Convert a time value represented as number of seconds since the -- Unix Epoch to a time value relative to an Ada implementation-defined -- Epoch. The units of the result are nanoseconds on all targets. Raises @@ -70,6 +74,12 @@ package Ada.Calendar.Conversions is function To_Duration (tv_sec : Interfaces.C.long; tv_nsec : Interfaces.C.long) return Duration; + pragma Obsolescent (To_Duration, "Retires in v26"); + -- Old version which will overflow at the 2038 Epochalypse + + function To_Duration_64 + (tv_sec : Interfaces.C.long_long; + tv_nsec : Interfaces.C.long) return Duration; -- Convert an elapsed time value expressed in Unix-like fields of struct -- timespec into a Duration value. The expected ranges are: @@ -80,6 +90,13 @@ package Ada.Calendar.Conversions is (D : Duration; tv_sec : out Interfaces.C.long; tv_nsec : out Interfaces.C.long); + pragma Obsolescent (To_Struct_Timespec, "Retires in v26"); + -- Old version which will overflow at the 2038 Epochalypse + + procedure To_Struct_Timespec_64 + (D : Duration; + tv_sec : out Interfaces.C.long_long; + tv_nsec : out Interfaces.C.long); -- Convert a Duration value into the constituents of struct timespec. -- Formal tv_sec denotes seconds and tv_nsecs denotes nanoseconds. @@ -105,6 +122,10 @@ package Ada.Calendar.Conversions is -- The input date is considered to be in UTC function To_Unix_Time (Ada_Time : Time) return Interfaces.C.long; + pragma Obsolescent (To_Unix_Time, "Retires in v26"); + -- Old version which will overflow at the 2038 Epochalypse + + function To_Unix_Time_64 (Ada_Time : Time) return Interfaces.C.long_long; -- Convert a time value represented as number of time units since the Ada -- implementation-defined Epoch to a value relative to the Unix Epoch. The -- units of the result are seconds. Raises Time_Error if the result cannot diff --git a/gcc/ada/libgnat/a-calend.adb b/gcc/ada/libgnat/a-calend.adb index c28042d13c4..21ab69315fa 100644 --- a/gcc/ada/libgnat/a-calend.adb +++ b/gcc/ada/libgnat/a-calend.adb @@ -897,6 +897,15 @@ is ----------------- function To_Ada_Time (Unix_Time : Long_Integer) return Time is + begin + return To_Ada_Time_64 (Long_Long_Integer (Unix_Time)); + end To_Ada_Time; + + -------------------- + -- To_Ada_Time_64 -- + -------------------- + + function To_Ada_Time_64 (Unix_Time : Long_Long_Integer) return Time is pragma Unsuppress (Overflow_Check); Ada_Rep : Time_Rep := Time_Rep (Unix_Time * Nano) - Epoch_Offset; @@ -928,7 +937,7 @@ is exception when Constraint_Error => raise Time_Error; - end To_Ada_Time; + end To_Ada_Time_64; ----------------- -- To_Ada_Time -- @@ -1018,11 +1027,23 @@ is function To_Duration (tv_sec : Long_Integer; tv_nsec : Long_Integer) return Duration + is + begin + return To_Duration_64 (Long_Long_Integer (tv_sec), tv_nsec); + end To_Duration; + + -------------------- + -- To_Duration_64 -- + -------------------- + + function To_Duration_64 + (tv_sec : Long_Long_Integer; + tv_nsec : Long_Integer) return Duration is pragma Unsuppress (Overflow_Check); begin return Duration (tv_sec) + Duration (tv_nsec) / Nano_F; - end To_Duration; + end To_Duration_64; ------------------------ -- To_Struct_Timespec -- @@ -1032,6 +1053,19 @@ is (D : Duration; tv_sec : out Long_Integer; tv_nsec : out Long_Integer) + is + begin + To_Struct_Timespec_64 (D, Long_Long_Integer (tv_sec), tv_nsec); + end To_Struct_Timespec; + + --------------------------- + -- To_Struct_Timespec_64 -- + --------------------------- + + procedure To_Struct_Timespec_64 + (D : Duration; + tv_sec : out Long_Long_Integer; + tv_nsec : out Long_Integer) is pragma Unsuppress (Overflow_Check); Secs : Duration; @@ -1041,13 +1075,13 @@ is -- Seconds extraction, avoid potential rounding errors Secs := D - 0.5; - tv_sec := Long_Integer (Secs); + tv_sec := Long_Long_Integer (Secs); -- Nanoseconds extraction Nano_Secs := D - Duration (tv_sec); tv_nsec := Long_Integer (Nano_Secs * Nano); - end To_Struct_Timespec; + end To_Struct_Timespec_64; ------------------ -- To_Struct_Tm -- @@ -1103,15 +1137,24 @@ is ------------------ function To_Unix_Time (Ada_Time : Time) return Long_Integer is + begin + return Long_Integer (To_Unix_Time_64 (Ada_Time)); + end To_Unix_Time; + + --------------------- + -- To_Unix_Time_64 -- + --------------------- + + function To_Unix_Time_64 (Ada_Time : Time) return Long_Long_Integer is pragma Unsuppress (Overflow_Check); Ada_Rep : constant Time_Rep := Time_Rep (Ada_Time); begin - return Long_Integer ((Ada_Rep + Epoch_Offset) / Nano) - - Long_Integer (Elapsed_Leaps (Start_Of_Time, Ada_Rep)); + return Long_Long_Integer ((Ada_Rep + Epoch_Offset) / Nano) - + Long_Long_Integer (Elapsed_Leaps (Start_Of_Time, Ada_Rep)); exception when Constraint_Error => raise Time_Error; - end To_Unix_Time; + end To_Unix_Time_64; end Conversion_Operations; ---------------------- diff --git a/gcc/ada/libgnat/a-calend.ads b/gcc/ada/libgnat/a-calend.ads index 9625f4d4153..64907455896 100644 --- a/gcc/ada/libgnat/a-calend.ads +++ b/gcc/ada/libgnat/a-calend.ads @@ -291,6 +291,10 @@ private package Conversion_Operations is function To_Ada_Time (Unix_Time : Long_Integer) return Time; + pragma Obsolescent (To_Ada_Time, "Retires in v26"); + -- Old Unix to Ada Epoch conversion + + function To_Ada_Time_64 (Unix_Time : Long_Long_Integer) return Time; -- Unix to Ada Epoch conversion function To_Ada_Time @@ -306,12 +310,25 @@ private function To_Duration (tv_sec : Long_Integer; tv_nsec : Long_Integer) return Duration; + pragma Obsolescent (To_Duration, "Retires in v26"); + -- Old Struct timespec to Duration conversion + + function To_Duration_64 + (tv_sec : Long_Long_Integer; + tv_nsec : Long_Integer) return Duration; -- Struct timespec to Duration conversion procedure To_Struct_Timespec (D : Duration; tv_sec : out Long_Integer; tv_nsec : out Long_Integer); + pragma Obsolescent (To_Struct_Timespec, "Retires in v26"); + -- Old Duration to struct timespec conversion + + procedure To_Struct_Timespec_64 + (D : Duration; + tv_sec : out Long_Long_Integer; + tv_nsec : out Long_Integer); -- Duration to struct timespec conversion procedure To_Struct_Tm @@ -325,6 +342,10 @@ private -- Time to struct tm conversion function To_Unix_Time (Ada_Time : Time) return Long_Integer; + pragma Obsolescent (To_Unix_Time, "Retires in v26"); + -- Old Ada to Unix Epoch conversion + + function To_Unix_Time_64 (Ada_Time : Time) return Long_Long_Integer; -- Ada to Unix Epoch conversion end Conversion_Operations; -- 2.43.0