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

Reply via email to