[libc-commits] [libc] ba46c37 - [libc] change the return value type of mktime_internal to time_t (#132231)

via libc-commits libc-commits at lists.llvm.org
Tue Mar 25 07:09:23 PDT 2025


Author: Leslie
Date: 2025-03-25T09:09:15-05:00
New Revision: ba46c37f9c56cb207c0c7189246456edef563340

URL: https://github.com/llvm/llvm-project/commit/ba46c37f9c56cb207c0c7189246456edef563340
DIFF: https://github.com/llvm/llvm-project/commit/ba46c37f9c56cb207c0c7189246456edef563340.diff

LOG: [libc] change the return value type of mktime_internal to time_t (#132231)

This pr is to resovle #126948

---------

Co-authored-by: Joseph Huber <huberjn at outlook.com>

Added: 
    

Modified: 
    libc/src/time/mktime.cpp
    libc/src/time/time_utils.cpp
    libc/src/time/time_utils.h

Removed: 
    


################################################################################
diff  --git a/libc/src/time/mktime.cpp b/libc/src/time/mktime.cpp
index fc05ff2930434..81652396e7fc2 100644
--- a/libc/src/time/mktime.cpp
+++ b/libc/src/time/mktime.cpp
@@ -15,13 +15,17 @@
 namespace LIBC_NAMESPACE_DECL {
 
 LLVM_LIBC_FUNCTION(time_t, mktime, (struct tm * tm_out)) {
-  int64_t seconds = time_utils::mktime_internal(tm_out);
+  auto mktime_result = time_utils::mktime_internal(tm_out);
+  if (!mktime_result)
+    return time_utils::out_of_range();
+
+  time_t seconds = *mktime_result;
 
   // Update the tm structure's year, month, day, etc. from seconds.
   if (time_utils::update_from_seconds(seconds, tm_out) < 0)
     return time_utils::out_of_range();
 
-  return static_cast<time_t>(seconds);
+  return seconds;
 }
 
 } // namespace LIBC_NAMESPACE_DECL

diff  --git a/libc/src/time/time_utils.cpp b/libc/src/time/time_utils.cpp
index 3ccb2dd934967..6e06deb30e354 100644
--- a/libc/src/time/time_utils.cpp
+++ b/libc/src/time/time_utils.cpp
@@ -18,7 +18,7 @@ namespace LIBC_NAMESPACE_DECL {
 namespace time_utils {
 
 // TODO: clean this up in a followup patch
-int64_t mktime_internal(const tm *tm_out) {
+cpp::optional<time_t> mktime_internal(const tm *tm_out) {
   // Unlike most C Library functions, mktime doesn't just die on bad input.
   // TODO(rtenneti); Handle leap seconds.
   int64_t tm_year_from_base = tm_out->tm_year + time_constants::TIME_YEAR_BASE;
@@ -27,20 +27,20 @@ int64_t mktime_internal(const tm *tm_out) {
   if (sizeof(time_t) == 4 &&
       tm_year_from_base >= time_constants::END_OF32_BIT_EPOCH_YEAR) {
     if (tm_year_from_base > time_constants::END_OF32_BIT_EPOCH_YEAR)
-      return time_utils::out_of_range();
+      return cpp::nullopt;
     if (tm_out->tm_mon > 0)
-      return time_utils::out_of_range();
+      return cpp::nullopt;
     if (tm_out->tm_mday > 19)
-      return time_utils::out_of_range();
+      return cpp::nullopt;
     else if (tm_out->tm_mday == 19) {
       if (tm_out->tm_hour > 3)
-        return time_utils::out_of_range();
+        return cpp::nullopt;
       else if (tm_out->tm_hour == 3) {
         if (tm_out->tm_min > 14)
-          return time_utils::out_of_range();
+          return cpp::nullopt;
         else if (tm_out->tm_min == 14) {
           if (tm_out->tm_sec > 7)
-            return time_utils::out_of_range();
+            return cpp::nullopt;
         }
       }
     }
@@ -102,10 +102,10 @@ int64_t mktime_internal(const tm *tm_out) {
 
   // TODO: https://github.com/llvm/llvm-project/issues/121962
   // Need to handle timezone and update of tm_isdst.
-  int64_t seconds = tm_out->tm_sec +
-                    tm_out->tm_min * time_constants::SECONDS_PER_MIN +
-                    tm_out->tm_hour * time_constants::SECONDS_PER_HOUR +
-                    total_days * time_constants::SECONDS_PER_DAY;
+  time_t seconds = tm_out->tm_sec +
+                   tm_out->tm_min * time_constants::SECONDS_PER_MIN +
+                   tm_out->tm_hour * time_constants::SECONDS_PER_HOUR +
+                   total_days * time_constants::SECONDS_PER_DAY;
   return seconds;
 }
 
@@ -136,7 +136,7 @@ static int64_t computeRemainingYears(int64_t daysPerYears,
 //
 // Compute the number of months from the remaining days. Finally, adjust years
 // to be 1900 and months to be from January.
-int64_t update_from_seconds(int64_t total_seconds, tm *tm) {
+int64_t update_from_seconds(time_t total_seconds, tm *tm) {
   // Days in month starting from March in the year 2000.
   static const char daysInMonth[] = {31 /* Mar */, 30, 31, 30, 31, 31,
                                      30,           31, 30, 31, 31, 29};
@@ -152,8 +152,7 @@ int64_t update_from_seconds(int64_t total_seconds, tm *tm) {
           : INT_MAX * static_cast<int64_t>(
                           time_constants::NUMBER_OF_SECONDS_IN_LEAP_YEAR);
 
-  time_t ts = static_cast<time_t>(total_seconds);
-  if (ts < time_min || ts > time_max)
+  if (total_seconds < time_min || total_seconds > time_max)
     return time_utils::out_of_range();
 
   int64_t seconds =

diff  --git a/libc/src/time/time_utils.h b/libc/src/time/time_utils.h
index 68eaac8c04f11..bbbb1c08a4759 100644
--- a/libc/src/time/time_utils.h
+++ b/libc/src/time/time_utils.h
@@ -26,11 +26,11 @@ namespace time_utils {
 
 // calculates the seconds from the epoch for tm_in. Does not update the struct,
 // you must call update_from_seconds for that.
-int64_t mktime_internal(const tm *tm_out);
+cpp::optional<time_t> mktime_internal(const tm *tm_out);
 
 // Update the "tm" structure's year, month, etc. members from seconds.
 // "total_seconds" is the number of seconds since January 1st, 1970.
-int64_t update_from_seconds(int64_t total_seconds, tm *tm);
+int64_t update_from_seconds(time_t total_seconds, tm *tm);
 
 // TODO(michaelrj): move these functions to use ErrorOr instead of setting
 // errno. They always accompany a specific return value so we only need the one
@@ -84,7 +84,7 @@ LIBC_INLINE char *asctime(const tm *timeptr, char *buffer,
 }
 
 LIBC_INLINE tm *gmtime_internal(const time_t *timer, tm *result) {
-  int64_t seconds = *timer;
+  time_t seconds = *timer;
   // Update the tm structure's year, month, day, etc. from seconds.
   if (update_from_seconds(seconds, result) < 0) {
     out_of_range();
@@ -329,7 +329,8 @@ class TMReader final {
   }
 
   LIBC_INLINE time_t get_epoch() const {
-    return static_cast<time_t>(mktime_internal(timeptr));
+    auto seconds = mktime_internal(timeptr);
+    return seconds ? *seconds : time_utils::out_of_range();
   }
 
   // returns the timezone offset in microwave time:


        


More information about the libc-commits mailing list