A recent regression caused by the parameterization of time_t was due to
the unusual declaration used for time_t in the interface to TZ functions
in sysdep.c. The root cause was the Long_Integer size of 32 bits used on
x86_64-windows. The incident was temporarily fixed by reverting the
declaration to its former self.

This however will break vxworks SR0660 use of 64-bit time_t on 32-bit
targets. The proper fix below is to use OS_Time for the interface to
ensure compatibility independent of Long_Integer size.

Tested on x86_64-pc-linux-gnu, committed on trunk

gcc/ada/

        * libgnat/a-calend.adb: Remove time_t, replace with OS_Time.
        * libgnat/s-os_lib.ads: Fix comments regarding time_t conversion
        functions to reflect the use of To_Ada in in Ada.Calendar
        package body.
        * sysdep.c (__gnat_localtime_tzoff): Use OS_Time instead of
        time_t.
diff --git a/gcc/ada/libgnat/a-calend.adb b/gcc/ada/libgnat/a-calend.adb
--- a/gcc/ada/libgnat/a-calend.adb
+++ b/gcc/ada/libgnat/a-calend.adb
@@ -35,6 +35,8 @@ with Interfaces.C;
 
 with System.OS_Primitives;
 
+with System.OS_Lib;
+
 package body Ada.Calendar with
   SPARK_Mode => Off
 is
@@ -685,13 +687,10 @@ is
       type int_Pointer  is access all Interfaces.C.int;
       type long_Pointer is access all Interfaces.C.long;
 
-      type time_t is
-        range -(2 ** (Standard'Address_Size - Integer'(1))) ..
-              +(2 ** (Standard'Address_Size - Integer'(1)) - 1);
-      type time_t_Pointer is access all time_t;
+      type OS_Time_Pointer is access all System.OS_Lib.OS_Time;
 
       procedure localtime_tzoff
-        (timer       : time_t_Pointer;
+        (timer       : OS_Time_Pointer;
          is_historic : int_Pointer;
          off         : long_Pointer);
       pragma Import (C, localtime_tzoff, "__gnat_localtime_tzoff");
@@ -708,7 +707,7 @@ is
       Date_N   : Time_Rep;
       Flag     : aliased Interfaces.C.int;
       Offset   : aliased Interfaces.C.long;
-      Secs_T   : aliased time_t;
+      Secs_T   : aliased System.OS_Lib.OS_Time;
 
    --  Start of processing for UTC_Time_Offset
 
@@ -745,7 +744,7 @@ is
 
       --  Convert the date into seconds
 
-      Secs_T := time_t (Date_N / Nano);
+      Secs_T := System.OS_Lib.To_Ada (Long_Long_Integer (Date_N / Nano));
 
       --  Determine whether to treat the input date as historical or not. A
       --  value of "0" signifies that the date is NOT historic.


diff --git a/gcc/ada/libgnat/s-os_lib.ads b/gcc/ada/libgnat/s-os_lib.ads
--- a/gcc/ada/libgnat/s-os_lib.ads
+++ b/gcc/ada/libgnat/s-os_lib.ads
@@ -169,16 +169,15 @@ package System.OS_Lib is
    ------------------
 
    --  Note: Do not use time_t in the compiler and host-based tools; instead
-   --  use OS_Time. These 3 declarations are intended for use only by consumers
-   --  of the GNAT.OS_Lib renaming of this package.
+   --  use OS_Time.
 
    subtype time_t is Long_Long_Integer;
-   --  C time_t can be either long or long long, but this is a subtype not used
-   --  in the compiler or tools, but only for user applications, so we choose
-   --  the Ada equivalent of the latter because eventually that will be the
+   --  C time_t can be either long or long long, so we choose the Ada
+   --  equivalent of the latter because eventually that will be the
    --  type used out of necessity. This may affect some user code on 32-bit
    --  targets that have not yet migrated to the Posix 2008 standard,
-   --  particularly pre version 5 32-bit Linux.
+   --  particularly pre version 5 32-bit Linux. Do not change this
+   --  declaration without coordinating it with conversions in Ada.Calendar.
 
    function To_C (Time : OS_Time) return time_t;
    --  Convert OS_Time to C time_t type


diff --git a/gcc/ada/sysdep.c b/gcc/ada/sysdep.c
--- a/gcc/ada/sysdep.c
+++ b/gcc/ada/sysdep.c
@@ -643,11 +643,11 @@ long __gnat_invalid_tzoff = 259273;
 /* Reentrant localtime for Windows. */
 
 extern void
-__gnat_localtime_tzoff (const time_t *, const int *, long *);
+__gnat_localtime_tzoff (const OS_Time *, const int *, long *);
 
 static const unsigned long long w32_epoch_offset = 11644473600ULL;
 void
-__gnat_localtime_tzoff (const time_t *timer, const int *is_historic, long *off)
+__gnat_localtime_tzoff (const OS_Time *timer, const int *is_historic, long *off)
 {
   TIME_ZONE_INFORMATION tzi;
 
@@ -737,10 +737,10 @@ __gnat_localtime_tzoff (const time_t *timer, const int *is_historic, long *off)
    the Lynx convention when building against the legacy API. */
 
 extern void
-__gnat_localtime_tzoff (const time_t *, const int *, long *);
+__gnat_localtime_tzoff (const OS_Time *, const int *, long *);
 
 void
-__gnat_localtime_tzoff (const time_t *timer, const int *is_historic, long *off)
+__gnat_localtime_tzoff (const OS_Time *timer, const int *is_historic, long *off)
 {
   *off = 0;
 }
@@ -756,21 +756,22 @@ extern void (*Lock_Task) (void);
 extern void (*Unlock_Task) (void);
 
 extern void
-__gnat_localtime_tzoff (const time_t *, const int *, long *);
+__gnat_localtime_tzoff (const OS_Time *, const int *, long *);
 
 void
-__gnat_localtime_tzoff (const time_t *timer ATTRIBUTE_UNUSED,
+__gnat_localtime_tzoff (const OS_Time *timer ATTRIBUTE_UNUSED,
 			const int *is_historic ATTRIBUTE_UNUSED,
 			long *off ATTRIBUTE_UNUSED)
 {
   struct tm tp ATTRIBUTE_UNUSED;
+  const time_t time = (time_t) *timer;
 
 /* AIX, HPUX, Sun Solaris */
 #if defined (_AIX) || defined (__hpux__) || defined (__sun__)
 {
   (*Lock_Task) ();
 
-  localtime_r (timer, &tp);
+  localtime_r (&time, &tp);
   *off = (long) -timezone;
 
   (*Unlock_Task) ();
@@ -787,7 +788,7 @@ __gnat_localtime_tzoff (const time_t *timer ATTRIBUTE_UNUSED,
 {
   (*Lock_Task) ();
 
-  localtime_r (timer, &tp);
+  localtime_r (&time, &tp);
 
   /* Try to read the environment variable TIMEZONE. The variable may not have
      been initialize, in that case return an offset of zero (0) for UTC. */
@@ -833,7 +834,7 @@ __gnat_localtime_tzoff (const time_t *timer ATTRIBUTE_UNUSED,
   || defined (__GLIBC__) || defined (__DragonFly__) || defined (__OpenBSD__) \
   || defined (__DJGPP__) || defined (__QNX__)
 {
-  localtime_r (timer, &tp);
+  localtime_r (&time, &tp);
   *off = tp.tm_gmtoff;
 }
 


Reply via email to