[clang] [clang] replaced the usage of `asctime` with `strftime` (PR #99075)

Yi-Chi Lee via cfe-commits cfe-commits at lists.llvm.org
Tue Jul 23 09:55:19 PDT 2024


https://github.com/yichi170 updated https://github.com/llvm/llvm-project/pull/99075

>From 0fcbd4a46bb05ad9829fcf33a9829fd5f5269c71 Mon Sep 17 00:00:00 2001
From: yichi170 <ilee900620 at gmail.com>
Date: Wed, 17 Jul 2024 02:15:43 +0800
Subject: [PATCH 1/4] [clang] replaced the usage of `asctime` with `strftime`

---
 clang/lib/Lex/PPMacroExpansion.cpp | 12 +++++++-----
 1 file changed, 7 insertions(+), 5 deletions(-)

diff --git a/clang/lib/Lex/PPMacroExpansion.cpp b/clang/lib/Lex/PPMacroExpansion.cpp
index 3913ff08c2eb5..f7e657be87932 100644
--- a/clang/lib/Lex/PPMacroExpansion.cpp
+++ b/clang/lib/Lex/PPMacroExpansion.cpp
@@ -1722,10 +1722,12 @@ void Preprocessor::ExpandBuiltinMacro(Token &Tok) {
     // MSVC, ICC, GCC, VisualAge C++ extension.  The generated string should be
     // of the form "Ddd Mmm dd hh::mm::ss yyyy", which is returned by asctime.
     const char *Result;
+    char TimeString[std::size("Ddd Mmm dd hh:mm:ss yyyy")];
     if (getPreprocessorOpts().SourceDateEpoch) {
       time_t TT = *getPreprocessorOpts().SourceDateEpoch;
       std::tm *TM = std::gmtime(&TT);
-      Result = asctime(TM);
+      strftime(TimeString, std::size(TimeString), "%c", TM);
+      Result = TimeString;
     } else {
       // Get the file that we are lexing out of.  If we're currently lexing from
       // a macro, dig into the include stack.
@@ -1735,13 +1737,13 @@ void Preprocessor::ExpandBuiltinMacro(Token &Tok) {
       if (CurFile) {
         time_t TT = CurFile->getModificationTime();
         struct tm *TM = localtime(&TT);
-        Result = asctime(TM);
+        strftime(TimeString, std::size(TimeString), "%c", TM);
+        Result = TimeString;
       } else {
-        Result = "??? ??? ?? ??:??:?? ????\n";
+        Result = "??? ??? ?? ??:??:?? ????";
       }
     }
-    // Surround the string with " and strip the trailing newline.
-    OS << '"' << StringRef(Result).drop_back() << '"';
+    OS << '"' << Result << '"';
     Tok.setKind(tok::string_literal);
   } else if (II == Ident__FLT_EVAL_METHOD__) {
     // __FLT_EVAL_METHOD__ is set to the default value.

>From 0352a494b6d0735ad83aa9189d33f2e50a1349d0 Mon Sep 17 00:00:00 2001
From: yichi170 <ilee900620 at gmail.com>
Date: Wed, 17 Jul 2024 22:17:48 +0800
Subject: [PATCH 2/4] [clang] handling zero return of `strgtime` in
 `clang/lib/Lex/PPMacroExpansion.cpp`

---
 clang/lib/Lex/PPMacroExpansion.cpp | 14 ++++++--------
 1 file changed, 6 insertions(+), 8 deletions(-)

diff --git a/clang/lib/Lex/PPMacroExpansion.cpp b/clang/lib/Lex/PPMacroExpansion.cpp
index f7e657be87932..89697872901d7 100644
--- a/clang/lib/Lex/PPMacroExpansion.cpp
+++ b/clang/lib/Lex/PPMacroExpansion.cpp
@@ -1721,13 +1721,13 @@ void Preprocessor::ExpandBuiltinMacro(Token &Tok) {
     Diag(Tok.getLocation(), diag::warn_pp_date_time);
     // MSVC, ICC, GCC, VisualAge C++ extension.  The generated string should be
     // of the form "Ddd Mmm dd hh::mm::ss yyyy", which is returned by asctime.
-    const char *Result;
-    char TimeString[std::size("Ddd Mmm dd hh:mm:ss yyyy")];
+    const char *Result = "??? ??? ?? ??:??:?? ????";
+    char TimeString[64];
     if (getPreprocessorOpts().SourceDateEpoch) {
       time_t TT = *getPreprocessorOpts().SourceDateEpoch;
       std::tm *TM = std::gmtime(&TT);
-      strftime(TimeString, std::size(TimeString), "%c", TM);
-      Result = TimeString;
+      if (strftime(TimeString, sizeof TimeString, "%a %b %e %T %Y", TM) != 0)
+        Result = TimeString;
     } else {
       // Get the file that we are lexing out of.  If we're currently lexing from
       // a macro, dig into the include stack.
@@ -1737,10 +1737,8 @@ void Preprocessor::ExpandBuiltinMacro(Token &Tok) {
       if (CurFile) {
         time_t TT = CurFile->getModificationTime();
         struct tm *TM = localtime(&TT);
-        strftime(TimeString, std::size(TimeString), "%c", TM);
-        Result = TimeString;
-      } else {
-        Result = "??? ??? ?? ??:??:?? ????";
+        if (strftime(TimeString, sizeof TimeString, "%a %b %e %T %Y", TM) != 0)
+          Result = TimeString;
       }
     }
     OS << '"' << Result << '"';

>From 3764d5de783e42cc3cd15faabe9d4fd29f5b31cd Mon Sep 17 00:00:00 2001
From: yichi170 <ilee900620 at gmail.com>
Date: Tue, 23 Jul 2024 08:35:39 +0800
Subject: [PATCH 3/4] [clang] replace the usage of `asctime` with
 `std::put_time`

---
 clang/lib/Lex/PPMacroExpansion.cpp | 18 ++++++++++++------
 1 file changed, 12 insertions(+), 6 deletions(-)

diff --git a/clang/lib/Lex/PPMacroExpansion.cpp b/clang/lib/Lex/PPMacroExpansion.cpp
index 89697872901d7..ea9c8e66d1a3d 100644
--- a/clang/lib/Lex/PPMacroExpansion.cpp
+++ b/clang/lib/Lex/PPMacroExpansion.cpp
@@ -52,7 +52,9 @@
 #include <cstddef>
 #include <cstring>
 #include <ctime>
+#include <iomanip>
 #include <optional>
+#include <sstream>
 #include <string>
 #include <tuple>
 #include <utility>
@@ -1721,13 +1723,15 @@ void Preprocessor::ExpandBuiltinMacro(Token &Tok) {
     Diag(Tok.getLocation(), diag::warn_pp_date_time);
     // MSVC, ICC, GCC, VisualAge C++ extension.  The generated string should be
     // of the form "Ddd Mmm dd hh::mm::ss yyyy", which is returned by asctime.
-    const char *Result = "??? ??? ?? ??:??:?? ????";
-    char TimeString[64];
+    std::string Result = "??? ??? ?? ??:??:?? ????";
+    std::stringstream TmpStream;
+    TmpStream.imbue(std::locale("C"));
+    TmpStream.setstate(std::ios_base::badbit);
     if (getPreprocessorOpts().SourceDateEpoch) {
       time_t TT = *getPreprocessorOpts().SourceDateEpoch;
       std::tm *TM = std::gmtime(&TT);
-      if (strftime(TimeString, sizeof TimeString, "%a %b %e %T %Y", TM) != 0)
-        Result = TimeString;
+      TmpStream.clear();
+      TmpStream << std::put_time(TM, "%a %b %e %T %Y");
     } else {
       // Get the file that we are lexing out of.  If we're currently lexing from
       // a macro, dig into the include stack.
@@ -1737,10 +1741,12 @@ void Preprocessor::ExpandBuiltinMacro(Token &Tok) {
       if (CurFile) {
         time_t TT = CurFile->getModificationTime();
         struct tm *TM = localtime(&TT);
-        if (strftime(TimeString, sizeof TimeString, "%a %b %e %T %Y", TM) != 0)
-          Result = TimeString;
+        TmpStream.clear();
+        TmpStream << std::put_time(TM, "%a %b %e %T %Y");
       }
     }
+    if (!TmpStream.bad())
+      Result = TmpStream.str();
     OS << '"' << Result << '"';
     Tok.setKind(tok::string_literal);
   } else if (II == Ident__FLT_EVAL_METHOD__) {

>From 5a8c840a034e79d4fd6b5168e8a7b6690828072a Mon Sep 17 00:00:00 2001
From: yichi170 <ilee900620 at gmail.com>
Date: Wed, 24 Jul 2024 00:54:58 +0800
Subject: [PATCH 4/4] [clang] check the result of `std::put_time` after
 materializing

---
 clang/lib/Lex/PPMacroExpansion.cpp | 10 ++++------
 1 file changed, 4 insertions(+), 6 deletions(-)

diff --git a/clang/lib/Lex/PPMacroExpansion.cpp b/clang/lib/Lex/PPMacroExpansion.cpp
index ea9c8e66d1a3d..879f01e87806e 100644
--- a/clang/lib/Lex/PPMacroExpansion.cpp
+++ b/clang/lib/Lex/PPMacroExpansion.cpp
@@ -1723,14 +1723,12 @@ void Preprocessor::ExpandBuiltinMacro(Token &Tok) {
     Diag(Tok.getLocation(), diag::warn_pp_date_time);
     // MSVC, ICC, GCC, VisualAge C++ extension.  The generated string should be
     // of the form "Ddd Mmm dd hh::mm::ss yyyy", which is returned by asctime.
-    std::string Result = "??? ??? ?? ??:??:?? ????";
+    std::string Result;
     std::stringstream TmpStream;
     TmpStream.imbue(std::locale("C"));
-    TmpStream.setstate(std::ios_base::badbit);
     if (getPreprocessorOpts().SourceDateEpoch) {
       time_t TT = *getPreprocessorOpts().SourceDateEpoch;
       std::tm *TM = std::gmtime(&TT);
-      TmpStream.clear();
       TmpStream << std::put_time(TM, "%a %b %e %T %Y");
     } else {
       // Get the file that we are lexing out of.  If we're currently lexing from
@@ -1741,12 +1739,12 @@ void Preprocessor::ExpandBuiltinMacro(Token &Tok) {
       if (CurFile) {
         time_t TT = CurFile->getModificationTime();
         struct tm *TM = localtime(&TT);
-        TmpStream.clear();
         TmpStream << std::put_time(TM, "%a %b %e %T %Y");
       }
     }
-    if (!TmpStream.bad())
-      Result = TmpStream.str();
+    Result = TmpStream.str();
+    if (Result.empty())
+      Result = "??? ??? ?? ??:??:?? ????";
     OS << '"' << Result << '"';
     Tok.setKind(tok::string_literal);
   } else if (II == Ident__FLT_EVAL_METHOD__) {



More information about the cfe-commits mailing list