Skip to content

Commit ba46c37

Browse files
wsehjkjhuber6
andauthored
[libc] change the return value type of mktime_internal to time_t (#132231)
This pr is to resovle #126948 --------- Co-authored-by: Joseph Huber <[email protected]>
1 parent f24cf59 commit ba46c37

File tree

3 files changed

+24
-20
lines changed

3 files changed

+24
-20
lines changed

libc/src/time/mktime.cpp

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,13 +15,17 @@
1515
namespace LIBC_NAMESPACE_DECL {
1616

1717
LLVM_LIBC_FUNCTION(time_t, mktime, (struct tm * tm_out)) {
18-
int64_t seconds = time_utils::mktime_internal(tm_out);
18+
auto mktime_result = time_utils::mktime_internal(tm_out);
19+
if (!mktime_result)
20+
return time_utils::out_of_range();
21+
22+
time_t seconds = *mktime_result;
1923

2024
// Update the tm structure's year, month, day, etc. from seconds.
2125
if (time_utils::update_from_seconds(seconds, tm_out) < 0)
2226
return time_utils::out_of_range();
2327

24-
return static_cast<time_t>(seconds);
28+
return seconds;
2529
}
2630

2731
} // namespace LIBC_NAMESPACE_DECL

libc/src/time/time_utils.cpp

Lines changed: 13 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ namespace LIBC_NAMESPACE_DECL {
1818
namespace time_utils {
1919

2020
// TODO: clean this up in a followup patch
21-
int64_t mktime_internal(const tm *tm_out) {
21+
cpp::optional<time_t> mktime_internal(const tm *tm_out) {
2222
// Unlike most C Library functions, mktime doesn't just die on bad input.
2323
// TODO(rtenneti); Handle leap seconds.
2424
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) {
2727
if (sizeof(time_t) == 4 &&
2828
tm_year_from_base >= time_constants::END_OF32_BIT_EPOCH_YEAR) {
2929
if (tm_year_from_base > time_constants::END_OF32_BIT_EPOCH_YEAR)
30-
return time_utils::out_of_range();
30+
return cpp::nullopt;
3131
if (tm_out->tm_mon > 0)
32-
return time_utils::out_of_range();
32+
return cpp::nullopt;
3333
if (tm_out->tm_mday > 19)
34-
return time_utils::out_of_range();
34+
return cpp::nullopt;
3535
else if (tm_out->tm_mday == 19) {
3636
if (tm_out->tm_hour > 3)
37-
return time_utils::out_of_range();
37+
return cpp::nullopt;
3838
else if (tm_out->tm_hour == 3) {
3939
if (tm_out->tm_min > 14)
40-
return time_utils::out_of_range();
40+
return cpp::nullopt;
4141
else if (tm_out->tm_min == 14) {
4242
if (tm_out->tm_sec > 7)
43-
return time_utils::out_of_range();
43+
return cpp::nullopt;
4444
}
4545
}
4646
}
@@ -102,10 +102,10 @@ int64_t mktime_internal(const tm *tm_out) {
102102

103103
// TODO: https://github.com/llvm/llvm-project/issues/121962
104104
// Need to handle timezone and update of tm_isdst.
105-
int64_t seconds = tm_out->tm_sec +
106-
tm_out->tm_min * time_constants::SECONDS_PER_MIN +
107-
tm_out->tm_hour * time_constants::SECONDS_PER_HOUR +
108-
total_days * time_constants::SECONDS_PER_DAY;
105+
time_t seconds = tm_out->tm_sec +
106+
tm_out->tm_min * time_constants::SECONDS_PER_MIN +
107+
tm_out->tm_hour * time_constants::SECONDS_PER_HOUR +
108+
total_days * time_constants::SECONDS_PER_DAY;
109109
return seconds;
110110
}
111111

@@ -136,7 +136,7 @@ static int64_t computeRemainingYears(int64_t daysPerYears,
136136
//
137137
// Compute the number of months from the remaining days. Finally, adjust years
138138
// to be 1900 and months to be from January.
139-
int64_t update_from_seconds(int64_t total_seconds, tm *tm) {
139+
int64_t update_from_seconds(time_t total_seconds, tm *tm) {
140140
// Days in month starting from March in the year 2000.
141141
static const char daysInMonth[] = {31 /* Mar */, 30, 31, 30, 31, 31,
142142
30, 31, 30, 31, 31, 29};
@@ -152,8 +152,7 @@ int64_t update_from_seconds(int64_t total_seconds, tm *tm) {
152152
: INT_MAX * static_cast<int64_t>(
153153
time_constants::NUMBER_OF_SECONDS_IN_LEAP_YEAR);
154154

155-
time_t ts = static_cast<time_t>(total_seconds);
156-
if (ts < time_min || ts > time_max)
155+
if (total_seconds < time_min || total_seconds > time_max)
157156
return time_utils::out_of_range();
158157

159158
int64_t seconds =

libc/src/time/time_utils.h

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -26,11 +26,11 @@ namespace time_utils {
2626

2727
// calculates the seconds from the epoch for tm_in. Does not update the struct,
2828
// you must call update_from_seconds for that.
29-
int64_t mktime_internal(const tm *tm_out);
29+
cpp::optional<time_t> mktime_internal(const tm *tm_out);
3030

3131
// Update the "tm" structure's year, month, etc. members from seconds.
3232
// "total_seconds" is the number of seconds since January 1st, 1970.
33-
int64_t update_from_seconds(int64_t total_seconds, tm *tm);
33+
int64_t update_from_seconds(time_t total_seconds, tm *tm);
3434

3535
// TODO(michaelrj): move these functions to use ErrorOr instead of setting
3636
// 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,
8484
}
8585

8686
LIBC_INLINE tm *gmtime_internal(const time_t *timer, tm *result) {
87-
int64_t seconds = *timer;
87+
time_t seconds = *timer;
8888
// Update the tm structure's year, month, day, etc. from seconds.
8989
if (update_from_seconds(seconds, result) < 0) {
9090
out_of_range();
@@ -329,7 +329,8 @@ class TMReader final {
329329
}
330330

331331
LIBC_INLINE time_t get_epoch() const {
332-
return static_cast<time_t>(mktime_internal(timeptr));
332+
auto seconds = mktime_internal(timeptr);
333+
return seconds ? *seconds : time_utils::out_of_range();
333334
}
334335

335336
// returns the timezone offset in microwave time:

0 commit comments

Comments
 (0)