[libc] Introduce asctime, asctime_r to LLVM libc
authorRaman Tenneti <rtenneti@google.com>
Wed, 31 Mar 2021 20:56:41 +0000 (13:56 -0700)
committerRaman Tenneti <rtenneti@google.com>
Tue, 4 May 2021 00:15:00 +0000 (17:15 -0700)
[libc] Introduce asctime, asctime_r to LLVM libc

asctime and asctime_r share the same common code. They call asctime_internal
a static inline function.

asctime uses snprintf to return the string representation in a buffer.
It uses the following format (26 characters is the buffer size) as per
7.27.3.1 section in http://www.open-std.org/jtc1/sc22/wg14/www/docs/n2478.pdf.
The buf parameter for asctime_r shall point to a buffer of at least 26 bytes.

snprintf(buf, 26, "%.3s %.3s%3d %.2d:%.2d:%.2d %d\n",...)

Reviewed By: sivachandra

Differential Revision: https://reviews.llvm.org/D99686

14 files changed:
libc/config/linux/api.td
libc/config/linux/x86_64/entrypoints.txt
libc/spec/stdc.td
libc/src/time/CMakeLists.txt
libc/src/time/asctime.cpp [new file with mode: 0644]
libc/src/time/asctime.h [new file with mode: 0644]
libc/src/time/asctime_r.cpp [new file with mode: 0644]
libc/src/time/asctime_r.h [new file with mode: 0644]
libc/src/time/time_utils.h
libc/test/src/time/CMakeLists.txt
libc/test/src/time/TmHelper.h [new file with mode: 0644]
libc/test/src/time/asctime_r_test.cpp [new file with mode: 0644]
libc/test/src/time/asctime_test.cpp [new file with mode: 0644]
libc/test/src/time/mktime_test.cpp

index 36067fb..c68888a 100644 (file)
@@ -249,6 +249,8 @@ def TimeAPI : PublicAPI<"time.h"> {
   ];
 
   let Functions = [
+    "asctime",
+    "asctime_r",
     "gmtime",
     "gmtime_r",
     "mktime",
index 678cc46..764059d 100644 (file)
@@ -181,6 +181,8 @@ if(LLVM_LIBC_FULL_BUILD)
     libc.src.threads.thrd_join
 
     # time.h entrypoints
+    libc.src.time.asctime
+    libc.src.time.asctime_r
     libc.src.time.gmtime
     libc.src.time.gmtime_r
     libc.src.time.mktime
index f771ad3..b50d2ed 100644 (file)
@@ -600,6 +600,19 @@ def StdC : StandardSpec<"stdc"> {
       [], // Enumerations
       [
           FunctionSpec<
+              "asctime",
+              RetValSpec<CharPtr>,
+              [ArgSpec<StructTmPtr>]
+          >,
+          FunctionSpec<
+              "asctime_r",
+              RetValSpec<CharPtr>,
+              [
+                  ArgSpec<StructTmPtr>,
+                  ArgSpec<CharPtr>,
+              ]
+          >,
+          FunctionSpec<
               "gmtime",
               RetValSpec<StructTmPtr>,
               [ArgSpec<TimeTTypePtr>]
index 03343cf..7e849cf 100644 (file)
@@ -11,6 +11,28 @@ add_object_library(
 )
 
 add_entrypoint_object(
+  asctime
+  SRCS
+    asctime.cpp
+  HDRS
+    asctime.h
+  DEPENDS
+    .time_utils
+    libc.include.time
+)
+
+add_entrypoint_object(
+  asctime_r
+  SRCS
+    asctime_r.cpp
+  HDRS
+    asctime_r.h
+  DEPENDS
+    .time_utils
+    libc.include.time
+)
+
+add_entrypoint_object(
   gmtime
   SRCS
     gmtime.cpp
diff --git a/libc/src/time/asctime.cpp b/libc/src/time/asctime.cpp
new file mode 100644 (file)
index 0000000..cdf5391
--- /dev/null
@@ -0,0 +1,22 @@
+//===-- Implementation of asctime function --------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "src/time/asctime.h"
+#include "src/__support/common.h"
+#include "src/time/time_utils.h"
+
+namespace __llvm_libc {
+
+using __llvm_libc::time_utils::TimeConstants;
+
+LLVM_LIBC_FUNCTION(char *, asctime, (const struct tm *timeptr)) {
+  static char buffer[TimeConstants::AsctimeBufferSize];
+  return time_utils::asctime(timeptr, buffer, TimeConstants::AsctimeMaxBytes);
+}
+
+} // namespace __llvm_libc
diff --git a/libc/src/time/asctime.h b/libc/src/time/asctime.h
new file mode 100644 (file)
index 0000000..9d75b40
--- /dev/null
@@ -0,0 +1,22 @@
+//===-- Implementation header of asctime ------------------------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_LIBC_SRC_TIME_ASCTIME_H
+#define LLVM_LIBC_SRC_TIME_ASCTIME_H
+
+#include <time.h>
+
+namespace __llvm_libc {
+
+char *asctime(const struct tm *timeptr);
+
+} // namespace __llvm_libc
+
+#endif // LLVM_LIBC_SRC_TIME_ASCTIME_H
+
+#include "include/time.h"
diff --git a/libc/src/time/asctime_r.cpp b/libc/src/time/asctime_r.cpp
new file mode 100644 (file)
index 0000000..fadc13e
--- /dev/null
@@ -0,0 +1,22 @@
+//===-- Implementation of asctime_r function ------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "src/time/asctime_r.h"
+#include "src/__support/common.h"
+#include "src/time/time_utils.h"
+
+namespace __llvm_libc {
+
+using __llvm_libc::time_utils::TimeConstants;
+
+LLVM_LIBC_FUNCTION(char *, asctime_r,
+                   (const struct tm *timeptr, char *buffer)) {
+  return time_utils::asctime(timeptr, buffer, TimeConstants::AsctimeMaxBytes);
+}
+
+} // namespace __llvm_libc
diff --git a/libc/src/time/asctime_r.h b/libc/src/time/asctime_r.h
new file mode 100644 (file)
index 0000000..8521e78
--- /dev/null
@@ -0,0 +1,22 @@
+//===-- Implementation header of asctime_r ----------------------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_LIBC_SRC_TIME_ASCTIME_R_H
+#define LLVM_LIBC_SRC_TIME_ASCTIME_R_H
+
+#include <time.h>
+
+namespace __llvm_libc {
+
+char *asctime_r(const struct tm *timeptr, char *buffer);
+
+} // namespace __llvm_libc
+
+#endif // LLVM_LIBC_SRC_TIME_ASCTIME_R_H
+
+#include "include/time.h"
index cca0300..c1c7735 100644 (file)
@@ -9,6 +9,8 @@
 #ifndef LLVM_LIBC_SRC_TIME_TIME_UTILS_H
 #define LLVM_LIBC_SRC_TIME_TIME_UTILS_H
 
+#include <stddef.h> // For size_t.
+
 #include "include/errno.h"
 
 #include "src/errno/llvmlibc_errno.h"
@@ -33,6 +35,14 @@ struct TimeConstants {
   static constexpr int NumberOfSecondsInLeapYear =
       (DaysPerNonLeapYear + 1) * SecondsPerDay;
 
+  // For asctime the behavior is undefined if struct tm's tm_wday or tm_mon are
+  // not within the normal ranges as defined in <time.h>, or if struct tm's
+  // tm_year exceeds {INT_MAX}-1990, or if the below asctime_internal algorithm
+  // would attempt to generate more than 26 bytes of output (including the
+  // terminating null).
+  static constexpr int AsctimeBufferSize = 256;
+  static constexpr int AsctimeMaxBytes = 26;
+
   /* 2000-03-01 (mod 400 year, immediately after feb29 */
   static constexpr int64_t SecondsUntil2000MarchFirst =
       (946684800LL + SecondsPerDay * (31 + 29));
@@ -63,6 +73,46 @@ static inline time_t OutOfRange() {
   return static_cast<time_t>(-1);
 }
 
+static inline void InvalidValue() { llvmlibc_errno = EINVAL; }
+
+static inline char *asctime(const struct tm *timeptr, char *buffer,
+                            size_t bufferLength) {
+  if (timeptr == nullptr || buffer == nullptr) {
+    InvalidValue();
+    return nullptr;
+  }
+  if (timeptr->tm_wday < 0 ||
+      timeptr->tm_wday > (TimeConstants::DaysPerWeek - 1)) {
+    InvalidValue();
+    return nullptr;
+  }
+  if (timeptr->tm_mon < 0 ||
+      timeptr->tm_mon > (TimeConstants::MonthsPerYear - 1)) {
+    InvalidValue();
+    return nullptr;
+  }
+
+  // TODO(rtenneti): i18n the following strings.
+  static const char *WeekDaysName[TimeConstants::DaysPerWeek] = {
+      "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"};
+
+  static const char *MonthsName[TimeConstants::MonthsPerYear] = {
+      "Jan", "Feb", "Mar", "Apr", "May", "Jun",
+      "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"};
+  int written_size = __builtin_snprintf(
+      buffer, bufferLength, "%.3s %.3s%3d %.2d:%.2d:%.2d %d\n",
+      WeekDaysName[timeptr->tm_wday], MonthsName[timeptr->tm_mon],
+      timeptr->tm_mday, timeptr->tm_hour, timeptr->tm_min, timeptr->tm_sec,
+      TimeConstants::TimeYearBase + timeptr->tm_year);
+  if (written_size < 0)
+    return nullptr;
+  if (static_cast<size_t>(written_size) >= bufferLength) {
+    OutOfRange();
+    return nullptr;
+  }
+  return buffer;
+}
+
 static inline struct tm *gmtime_internal(const time_t *timer,
                                          struct tm *result) {
   int64_t seconds = *timer;
index e3bf5e2..514a6fa 100644 (file)
@@ -1,6 +1,32 @@
 add_libc_testsuite(libc_time_unittests)
 
 add_libc_unittest(
+  asctime
+  SUITE
+    libc_time_unittests
+  SRCS
+    asctime_test.cpp
+  HDRS
+    TmHelper.h
+    TmMatcher.h
+  DEPENDS
+    libc.src.time.asctime
+)
+
+add_libc_unittest(
+  asctime_r
+  SUITE
+    libc_time_unittests
+  SRCS
+    asctime_r_test.cpp
+  HDRS
+    TmHelper.h
+    TmMatcher.h
+  DEPENDS
+    libc.src.time.asctime_r
+)
+
+add_libc_unittest(
   gmtime
   SUITE
     libc_time_unittests
@@ -31,6 +57,7 @@ add_libc_unittest(
   SRCS
     mktime_test.cpp
   HDRS
+    TmHelper.h
     TmMatcher.h
   DEPENDS
     libc.src.time.mktime
diff --git a/libc/test/src/time/TmHelper.h b/libc/test/src/time/TmHelper.h
new file mode 100644 (file)
index 0000000..6a0b3ed
--- /dev/null
@@ -0,0 +1,42 @@
+//===---- TmHelper.h ------------------------------------------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_LIBC_TEST_SRC_TIME_TM_HELPER_H
+#define LLVM_LIBC_TEST_SRC_TIME_TM_HELPER_H
+
+#include <time.h>
+
+#include "src/time/time_utils.h"
+
+using __llvm_libc::time_utils::TimeConstants;
+
+namespace __llvm_libc {
+namespace tmhelper {
+namespace testing {
+
+// A helper function to initialize tm data structure.
+static inline void InitializeTmData(struct tm *tm_data, int year, int month,
+                                    int mday, int hour, int min, int sec,
+                                    int wday, int yday) {
+  struct tm temp = {.tm_sec = sec,
+                    .tm_min = min,
+                    .tm_hour = hour,
+                    .tm_mday = mday,
+                    .tm_mon = month - 1, // tm_mon starts with 0 for Jan
+                    // years since 1900
+                    .tm_year = year - TimeConstants::TimeYearBase,
+                    .tm_wday = wday,
+                    .tm_yday = yday};
+  *tm_data = temp;
+}
+
+} // namespace testing
+} // namespace tmhelper
+} // namespace __llvm_libc
+
+#endif // LLVM_LIBC_TEST_SRC_TIME_TM_HELPER_H
diff --git a/libc/test/src/time/asctime_r_test.cpp b/libc/test/src/time/asctime_r_test.cpp
new file mode 100644 (file)
index 0000000..66db441
--- /dev/null
@@ -0,0 +1,60 @@
+//===-- Unittests for asctime_r
+//--------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "src/time/asctime_r.h"
+#include "src/time/time_utils.h"
+#include "test/src/time/TmHelper.h"
+#include "utils/UnitTest/Test.h"
+
+using __llvm_libc::time_utils::TimeConstants;
+
+static inline char *call_asctime_r(struct tm *tm_data, int year, int month,
+                                   int mday, int hour, int min, int sec,
+                                   int wday, int yday, char *buffer) {
+  __llvm_libc::tmhelper::testing::InitializeTmData(tm_data, year, month, mday,
+                                                   hour, min, sec, wday, yday);
+  return __llvm_libc::asctime_r(tm_data, buffer);
+}
+
+// asctime and asctime_r share the same code and thus didn't repeat all the
+// tests from asctime. Added couple of validation tests.
+TEST(LlvmLibcAsctimeR, Nullptr) {
+  char *result;
+  result = __llvm_libc::asctime_r(nullptr, nullptr);
+  ASSERT_EQ(EINVAL, llvmlibc_errno);
+  ASSERT_STREQ(nullptr, result);
+
+  char buffer[TimeConstants::AsctimeBufferSize];
+  result = __llvm_libc::asctime_r(nullptr, buffer);
+  ASSERT_EQ(EINVAL, llvmlibc_errno);
+  ASSERT_STREQ(nullptr, result);
+
+  struct tm tm_data;
+  result = __llvm_libc::asctime_r(&tm_data, nullptr);
+  ASSERT_EQ(EINVAL, llvmlibc_errno);
+  ASSERT_STREQ(nullptr, result);
+}
+
+TEST(LlvmLibcAsctimeR, ValidDate) {
+  char buffer[TimeConstants::AsctimeBufferSize];
+  struct tm tm_data;
+  char *result;
+  // 1970-01-01 00:00:00. Test with a valid buffer size.
+  result = call_asctime_r(&tm_data,
+                          1970, // year
+                          1,    // month
+                          1,    // day
+                          0,    // hr
+                          0,    // min
+                          0,    // sec
+                          4,    // wday
+                          0,    // yday
+                          buffer);
+  ASSERT_STREQ("Thu Jan  1 00:00:00 1970\n", result);
+}
diff --git a/libc/test/src/time/asctime_test.cpp b/libc/test/src/time/asctime_test.cpp
new file mode 100644 (file)
index 0000000..14201fd
--- /dev/null
@@ -0,0 +1,215 @@
+//===-- Unittests for asctime ---------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "src/time/asctime.h"
+#include "test/src/time/TmHelper.h"
+#include "utils/UnitTest/Test.h"
+
+static inline char *call_asctime(struct tm *tm_data, int year, int month,
+                                 int mday, int hour, int min, int sec, int wday,
+                                 int yday) {
+  __llvm_libc::tmhelper::testing::InitializeTmData(tm_data, year, month, mday,
+                                                   hour, min, sec, wday, yday);
+  return __llvm_libc::asctime(tm_data);
+}
+
+TEST(LlvmLibcAsctime, Nullptr) {
+  char *result;
+  result = __llvm_libc::asctime(nullptr);
+  ASSERT_EQ(EINVAL, llvmlibc_errno);
+  ASSERT_STREQ(nullptr, result);
+}
+
+// Weekdays are in the range 0 to 6. Test passing invalid value in wday.
+TEST(LlvmLibcAsctime, InvalidWday) {
+  struct tm tm_data;
+  char *result;
+
+  // Test with wday = -1.
+  result = call_asctime(&tm_data,
+                        1970, // year
+                        1,    // month
+                        1,    // day
+                        0,    // hr
+                        0,    // min
+                        0,    // sec
+                        -1,   // wday
+                        0);   // yday
+  ASSERT_EQ(EINVAL, llvmlibc_errno);
+
+  // Test with wday = 7.
+  result = call_asctime(&tm_data,
+                        1970, // year
+                        1,    // month
+                        1,    // day
+                        0,    // hr
+                        0,    // min
+                        0,    // sec
+                        7,    // wday
+                        0);   // yday
+  ASSERT_EQ(EINVAL, llvmlibc_errno);
+}
+
+// Months are from January to December. Test passing invalid value in month.
+TEST(LlvmLibcAsctime, InvalidMonth) {
+  struct tm tm_data;
+  char *result;
+
+  // Test with month = 0.
+  result = call_asctime(&tm_data,
+                        1970, // year
+                        0,    // month
+                        1,    // day
+                        0,    // hr
+                        0,    // min
+                        0,    // sec
+                        4,    // wday
+                        0);   // yday
+  ASSERT_EQ(EINVAL, llvmlibc_errno);
+
+  // Test with month = 13.
+  result = call_asctime(&tm_data,
+                        1970, // year
+                        13,   // month
+                        1,    // day
+                        0,    // hr
+                        0,    // min
+                        0,    // sec
+                        4,    // wday
+                        0);   // yday
+  ASSERT_EQ(EINVAL, llvmlibc_errno);
+}
+
+TEST(LlvmLibcAsctime, ValidWeekdays) {
+  struct tm tm_data;
+  char *result;
+  // 1970-01-01 00:00:00.
+  result = call_asctime(&tm_data,
+                        1970, // year
+                        1,    // month
+                        1,    // day
+                        0,    // hr
+                        0,    // min
+                        0,    // sec
+                        4,    // wday
+                        0);   // yday
+  ASSERT_STREQ("Thu Jan  1 00:00:00 1970\n", result);
+
+  // 1970-01-03 00:00:00.
+  result = call_asctime(&tm_data,
+                        1970, // year
+                        1,    // month
+                        3,    // day
+                        0,    // hr
+                        0,    // min
+                        0,    // sec
+                        6,    // wday
+                        0);   // yday
+  ASSERT_STREQ("Sat Jan  3 00:00:00 1970\n", result);
+
+  // 1970-01-04 00:00:00.
+  result = call_asctime(&tm_data,
+                        1970, // year
+                        1,    // month
+                        4,    // day
+                        0,    // hr
+                        0,    // min
+                        0,    // sec
+                        0,    // wday
+                        0);   // yday
+  ASSERT_STREQ("Sun Jan  4 00:00:00 1970\n", result);
+}
+
+TEST(LlvmLibcAsctime, ValidMonths) {
+  struct tm tm_data;
+  char *result;
+  // 1970-01-01 00:00:00.
+  result = call_asctime(&tm_data,
+                        1970, // year
+                        1,    // month
+                        1,    // day
+                        0,    // hr
+                        0,    // min
+                        0,    // sec
+                        4,    // wday
+                        0);   // yday
+  ASSERT_STREQ("Thu Jan  1 00:00:00 1970\n", result);
+
+  // 1970-02-01 00:00:00.
+  result = call_asctime(&tm_data,
+                        1970, // year
+                        2,    // month
+                        1,    // day
+                        0,    // hr
+                        0,    // min
+                        0,    // sec
+                        0,    // wday
+                        0);   // yday
+  ASSERT_STREQ("Sun Feb  1 00:00:00 1970\n", result);
+
+  // 1970-12-31 23:59:59.
+  result = call_asctime(&tm_data,
+                        1970, // year
+                        12,   // month
+                        31,   // day
+                        23,   // hr
+                        59,   // min
+                        59,   // sec
+                        4,    // wday
+                        0);   // yday
+  ASSERT_STREQ("Thu Dec 31 23:59:59 1970\n", result);
+}
+
+TEST(LlvmLibcAsctime, EndOf32BitEpochYear) {
+  struct tm tm_data;
+  char *result;
+  // Test for maximum value of a signed 32-bit integer.
+  // Test implementation can encode time for Tue 19 January 2038 03:14:07 UTC.
+  result = call_asctime(&tm_data,
+                        2038, // year
+                        1,    // month
+                        19,   // day
+                        3,    // hr
+                        14,   // min
+                        7,    // sec
+                        2,    // wday
+                        7);   // yday
+  ASSERT_STREQ("Tue Jan 19 03:14:07 2038\n", result);
+}
+
+TEST(LlvmLibcAsctime, Max64BitYear) {
+  if (sizeof(time_t) == 4)
+    return;
+  // Mon Jan 1 12:50:50 2170 (200 years from 1970),
+  struct tm tm_data;
+  char *result;
+  result = call_asctime(&tm_data,
+                        2170, // year
+                        1,    // month
+                        1,    // day
+                        12,   // hr
+                        50,   // min
+                        50,   // sec
+                        1,    // wday
+                        50);  // yday
+  ASSERT_STREQ("Mon Jan  1 12:50:50 2170\n", result);
+
+  // Test for Tue Jan 1 12:50:50 in 2,147,483,647th year.
+  // This test would cause buffer overflow and thus asctime returns nullptr.
+  result = call_asctime(&tm_data,
+                        2147483647, // year
+                        1,          // month
+                        1,          // day
+                        12,         // hr
+                        50,         // min
+                        50,         // sec
+                        2,          // wday
+                        50);        // yday
+  ASSERT_EQ(EOVERFLOW, llvmlibc_errno);
+  ASSERT_STREQ(nullptr, result);
+}
index 93290d3..b9ea4ed 100644 (file)
@@ -9,6 +9,7 @@
 #include "src/time/mktime.h"
 #include "src/time/time_utils.h"
 #include "test/ErrnoSetterMatcher.h"
+#include "test/src/time/TmHelper.h"
 #include "test/src/time/TmMatcher.h"
 #include "utils/UnitTest/Test.h"
 
@@ -20,33 +21,18 @@ using __llvm_libc::testing::ErrnoSetterMatcher::Fails;
 using __llvm_libc::testing::ErrnoSetterMatcher::Succeeds;
 using __llvm_libc::time_utils::TimeConstants;
 
-// A helper function to initialize tm data structure.
-static inline void initialize_tm_data(struct tm *tm_data, int year, int month,
-                                      int mday, int hour, int min, int sec,
-                                      int wday, int yday) {
-  struct tm temp = {.tm_sec = sec,
-                    .tm_min = min,
-                    .tm_hour = hour,
-                    .tm_mday = mday,
-                    .tm_mon = month - 1, // tm_mon starts with 0 for Jan
-                    // years since 1900
-                    .tm_year = year - TimeConstants::TimeYearBase,
-                    .tm_wday = wday,
-                    .tm_yday = yday};
-  *tm_data = temp;
-}
-
 static inline time_t call_mktime(struct tm *tm_data, int year, int month,
                                  int mday, int hour, int min, int sec, int wday,
                                  int yday) {
-  initialize_tm_data(tm_data, year, month, mday, hour, min, sec, wday, yday);
+  __llvm_libc::tmhelper::testing::InitializeTmData(tm_data, year, month, mday,
+                                                   hour, min, sec, wday, yday);
   return __llvm_libc::mktime(tm_data);
 }
 
 TEST(LlvmLibcMkTime, FailureSetsErrno) {
   struct tm tm_data;
-  initialize_tm_data(&tm_data, INT_MAX, INT_MAX, INT_MAX, INT_MAX, INT_MAX, -1,
-                     0, 0);
+  __llvm_libc::tmhelper::testing::InitializeTmData(
+      &tm_data, INT_MAX, INT_MAX, INT_MAX, INT_MAX, INT_MAX, -1, 0, 0);
   EXPECT_THAT(__llvm_libc::mktime(&tm_data), Fails(EOVERFLOW));
 }