[clang] [clang-tools-extra] [clang-tidy] add `ctime` and `localtime` to `clang-tidy` (PR #110366)

Зишан Мирза via cfe-commits cfe-commits at lists.llvm.org
Mon Sep 30 11:10:45 PDT 2024


https://github.com/zimirza updated https://github.com/llvm/llvm-project/pull/110366

>From 4fb69942effb3cf34d07f33a14a95757b6ca5ee0 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?=D0=97=D0=B8=D1=88=D0=B0=D0=BD=20=D0=9C=D0=B8=D1=80=D0=B7?=
 =?UTF-8?q?=D0=B0?= <zmirza at tutanota.de>
Date: Sat, 28 Sep 2024 17:05:42 +0200
Subject: [PATCH 01/25] [clang-tidy] add `ctime` and `localtime` to
 `clang-tidy`

Closes #107445
---
 clang/docs/tools/clang-formatted-files.txt               | 8 ++++++++
 .../StaticAnalyzer/Checkers/cert/InvalidPtrChecker.cpp   | 4 ++++
 clang/lib/Tooling/Inclusions/Stdlib/CSymbolMap.inc       | 4 ++++
 clang/lib/Tooling/Inclusions/Stdlib/StdSymbolMap.inc     | 6 ++++++
 clang/test/Analysis/cert/env34-c.c                       | 9 ++++++++-
 5 files changed, 30 insertions(+), 1 deletion(-)

diff --git a/clang/docs/tools/clang-formatted-files.txt b/clang/docs/tools/clang-formatted-files.txt
index 67ff085144f4de..5223ca82a5b575 100644
--- a/clang/docs/tools/clang-formatted-files.txt
+++ b/clang/docs/tools/clang-formatted-files.txt
@@ -3058,6 +3058,14 @@ libc/src/threads/linux/thrd_join.cpp
 libc/src/threads/linux/Thread.h
 libc/src/time/asctime.cpp
 libc/src/time/asctime.h
+libc/src/time/ctime.cpp
+libc/src/time/ctime.h
+libc/src/time/ctime_r.cpp
+libc/src/time/ctime_r.h
+libc/src/time/localtime.cpp
+libc/src/time/localtime.h
+libc/src/time/localtime_r.cpp
+libc/src/time/localtime_r.h
 libc/src/time/asctime_r.cpp
 libc/src/time/asctime_r.h
 libc/src/time/gmtime.cpp
diff --git a/clang/lib/StaticAnalyzer/Checkers/cert/InvalidPtrChecker.cpp b/clang/lib/StaticAnalyzer/Checkers/cert/InvalidPtrChecker.cpp
index fefe846b6911f7..9c34d3636c8488 100644
--- a/clang/lib/StaticAnalyzer/Checkers/cert/InvalidPtrChecker.cpp
+++ b/clang/lib/StaticAnalyzer/Checkers/cert/InvalidPtrChecker.cpp
@@ -76,6 +76,10 @@ class InvalidPtrChecker
        &InvalidPtrChecker::postPreviousReturnInvalidatingCall},
       {{CDM::CLibrary, {"asctime"}, 1},
        &InvalidPtrChecker::postPreviousReturnInvalidatingCall},
+      {{CDM::CLibrary, {"ctime"}, 1},
+       &InvalidPtrChecker::postPreviousReturnInvalidatingCall},
+      {{CDM::CLibrary, {"localtime"}, 1},
+       &InvalidPtrChecker::postPreviousReturnInvalidatingCall},
   };
 
   // The private members of this checker corresponding to commandline options
diff --git a/clang/lib/Tooling/Inclusions/Stdlib/CSymbolMap.inc b/clang/lib/Tooling/Inclusions/Stdlib/CSymbolMap.inc
index 463ce921f0672f..aca22f869b5291 100644
--- a/clang/lib/Tooling/Inclusions/Stdlib/CSymbolMap.inc
+++ b/clang/lib/Tooling/Inclusions/Stdlib/CSymbolMap.inc
@@ -220,6 +220,10 @@ SYMBOL(and, None, <iso646.h>)
 SYMBOL(and_eq, None, <iso646.h>)
 SYMBOL(asctime, None, <time.h>)
 SYMBOL(asctime_s, None, <time.h>)
+SYMBOL(ctime, None, <time.h>)
+SYMBOL(ctime_s, None, <time.h>)
+SYMBOL(localtime, None, <time.h>)
+SYMBOL(localtime_s, None, <time.h>)
 SYMBOL(asin, None, <math.h>)
 SYMBOL(asinf, None, <math.h>)
 SYMBOL(asinh, None, <math.h>)
diff --git a/clang/lib/Tooling/Inclusions/Stdlib/StdSymbolMap.inc b/clang/lib/Tooling/Inclusions/Stdlib/StdSymbolMap.inc
index b46bd2e4d7a4b5..8e3471e2fc5729 100644
--- a/clang/lib/Tooling/Inclusions/Stdlib/StdSymbolMap.inc
+++ b/clang/lib/Tooling/Inclusions/Stdlib/StdSymbolMap.inc
@@ -617,6 +617,12 @@ SYMBOL(as_writable_bytes, std::, <span>)
 SYMBOL(asctime, std::, <ctime>)
 SYMBOL(asctime, None, <ctime>)
 SYMBOL(asctime, None, <time.h>)
+SYMBOL(ctime, std::, <time.h>)
+SYMBOL(ctime, None, <ctime>)
+SYMBOL(ctime, None, <time.h>)
+SYMBOL(localtime, std::, <ctime>)
+SYMBOL(localtime, None, <ctime>)
+SYMBOL(localtime, None, <time.h>)
 SYMBOL(asin, std::, <cmath>)
 SYMBOL(asin, None, <cmath>)
 SYMBOL(asin, None, <math.h>)
diff --git a/clang/test/Analysis/cert/env34-c.c b/clang/test/Analysis/cert/env34-c.c
index d307f0d8f4bb01..66ba0be4a67bba 100644
--- a/clang/test/Analysis/cert/env34-c.c
+++ b/clang/test/Analysis/cert/env34-c.c
@@ -15,7 +15,14 @@ lconv *localeconv(void);
 
 typedef struct {
 } tm;
-char *asctime(const tm *timeptr);
+char *asctime(const tm *timeptr)
+;
+typedef struct {
+} tm;
+char *ctime(const tm *timeptr);
+typedef struct {
+} tm;
+struct tm *localtime(struct tm *tm);
 
 int strcmp(const char*, const char*);
 extern void foo(char *e);

>From 5be47623b21694a8f98eb6e5de0e536fdbb4ca0a Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?=D0=97=D0=B8=D1=88=D0=B0=D0=BD=20=D0=9C=D0=B8=D1=80=D0=B7?=
 =?UTF-8?q?=D0=B0?= <zmirza at tutanota.de>
Date: Sat, 28 Sep 2024 17:20:00 +0200
Subject: [PATCH 02/25] [clang-tidy] add times to clang-tidy

add `ctime` and `localtime` to unsafe functions check function
---
 clang-tools-extra/clang-tidy/bugprone/UnsafeFunctionsCheck.cpp | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/clang-tools-extra/clang-tidy/bugprone/UnsafeFunctionsCheck.cpp b/clang-tools-extra/clang-tidy/bugprone/UnsafeFunctionsCheck.cpp
index 604a7cac0e4903..f058e5ae40680f 100644
--- a/clang-tools-extra/clang-tidy/bugprone/UnsafeFunctionsCheck.cpp
+++ b/clang-tools-extra/clang-tidy/bugprone/UnsafeFunctionsCheck.cpp
@@ -50,6 +50,8 @@ static StringRef getReplacementFor(StringRef FunctionName,
     StringRef AnnexKReplacementFunction =
         StringSwitch<StringRef>(FunctionName)
             .Cases("asctime", "asctime_r", "asctime_s")
+            .Cases("ctime", "ctime_r")
+            .Cases("localtime", "localtime_r")
             .Case("gets", "gets_s")
             .Default({});
     if (!AnnexKReplacementFunction.empty())

>From 5deca5d7b330b6e8bdf27862813c7c2acb5c9f77 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?=D0=97=D0=B8=D1=88=D0=B0=D0=BD=20=D0=9C=D0=B8=D1=80=D0=B7?=
 =?UTF-8?q?=D0=B0?= <zmirza at tutanota.de>
Date: Mon, 30 Sep 2024 16:35:31 +0200
Subject: [PATCH 03/25] [clang-tidy] add `ctime` and `localtime` to
 `clang-tidy`

add changes to release notes
---
 clang-tools-extra/docs/ReleaseNotes.rst | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/clang-tools-extra/docs/ReleaseNotes.rst b/clang-tools-extra/docs/ReleaseNotes.rst
index 7d37a4b03222cf..42ddb3c1b76c87 100644
--- a/clang-tools-extra/docs/ReleaseNotes.rst
+++ b/clang-tools-extra/docs/ReleaseNotes.rst
@@ -97,6 +97,8 @@ The improvements are...
 Improvements to clang-tidy
 --------------------------
 
+- Added `ctime` and `localtime` to clang-tidy.
+
 - Improved :program:`run-clang-tidy.py` script. Fixed minor shutdown noise
   happening on certain platforms when interrupting the script.
 

>From 377ef53a4e6b8c5f5c4af7c303dc8aae9deeaad4 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?=D0=97=D0=B8=D1=88=D0=B0=D0=BD=20=D0=9C=D0=B8=D1=80=D0=B7?=
 =?UTF-8?q?=D0=B0?= <zmirza at tutanota.de>
Date: Mon, 30 Sep 2024 16:42:07 +0200
Subject: [PATCH 04/25] [clang-tidy] add `ctime` and `localtime` to
 `clang-tidy`

fix: tests
---
 clang/test/Analysis/cert/env34-c.c | 7 +------
 1 file changed, 1 insertion(+), 6 deletions(-)

diff --git a/clang/test/Analysis/cert/env34-c.c b/clang/test/Analysis/cert/env34-c.c
index 66ba0be4a67bba..ae344a815679ec 100644
--- a/clang/test/Analysis/cert/env34-c.c
+++ b/clang/test/Analysis/cert/env34-c.c
@@ -15,13 +15,8 @@ lconv *localeconv(void);
 
 typedef struct {
 } tm;
-char *asctime(const tm *timeptr)
-;
-typedef struct {
-} tm;
+char *asctime(const tm *timeptr);
 char *ctime(const tm *timeptr);
-typedef struct {
-} tm;
 struct tm *localtime(struct tm *tm);
 
 int strcmp(const char*, const char*);

>From 564c8577e002f40075306e2e351ab3d27eabe74b Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?=D0=97=D0=B8=D1=88=D0=B0=D0=BD=20=D0=9C=D0=B8=D1=80=D0=B7?=
 =?UTF-8?q?=D0=B0?= <zmirza at tutanota.de>
Date: Mon, 30 Sep 2024 16:58:06 +0200
Subject: [PATCH 05/25] undo symbols, since these should be automatically
 generated

---
 clang/lib/Tooling/Inclusions/Stdlib/CSymbolMap.inc   | 4 ----
 clang/lib/Tooling/Inclusions/Stdlib/StdSymbolMap.inc | 6 ------
 2 files changed, 10 deletions(-)

diff --git a/clang/lib/Tooling/Inclusions/Stdlib/CSymbolMap.inc b/clang/lib/Tooling/Inclusions/Stdlib/CSymbolMap.inc
index aca22f869b5291..463ce921f0672f 100644
--- a/clang/lib/Tooling/Inclusions/Stdlib/CSymbolMap.inc
+++ b/clang/lib/Tooling/Inclusions/Stdlib/CSymbolMap.inc
@@ -220,10 +220,6 @@ SYMBOL(and, None, <iso646.h>)
 SYMBOL(and_eq, None, <iso646.h>)
 SYMBOL(asctime, None, <time.h>)
 SYMBOL(asctime_s, None, <time.h>)
-SYMBOL(ctime, None, <time.h>)
-SYMBOL(ctime_s, None, <time.h>)
-SYMBOL(localtime, None, <time.h>)
-SYMBOL(localtime_s, None, <time.h>)
 SYMBOL(asin, None, <math.h>)
 SYMBOL(asinf, None, <math.h>)
 SYMBOL(asinh, None, <math.h>)
diff --git a/clang/lib/Tooling/Inclusions/Stdlib/StdSymbolMap.inc b/clang/lib/Tooling/Inclusions/Stdlib/StdSymbolMap.inc
index 8e3471e2fc5729..b46bd2e4d7a4b5 100644
--- a/clang/lib/Tooling/Inclusions/Stdlib/StdSymbolMap.inc
+++ b/clang/lib/Tooling/Inclusions/Stdlib/StdSymbolMap.inc
@@ -617,12 +617,6 @@ SYMBOL(as_writable_bytes, std::, <span>)
 SYMBOL(asctime, std::, <ctime>)
 SYMBOL(asctime, None, <ctime>)
 SYMBOL(asctime, None, <time.h>)
-SYMBOL(ctime, std::, <time.h>)
-SYMBOL(ctime, None, <ctime>)
-SYMBOL(ctime, None, <time.h>)
-SYMBOL(localtime, std::, <ctime>)
-SYMBOL(localtime, None, <ctime>)
-SYMBOL(localtime, None, <time.h>)
 SYMBOL(asin, std::, <cmath>)
 SYMBOL(asin, None, <cmath>)
 SYMBOL(asin, None, <math.h>)

>From 6d388c05a4ec3de5bc7227e4caa4c1477e0b8e46 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?=D0=97=D0=B8=D1=88=D0=B0=D0=BD=20=D0=9C=D0=B8=D1=80=D0=B7?=
 =?UTF-8?q?=D0=B0?= <zmirza at tutanota.de>
Date: Mon, 30 Sep 2024 17:00:51 +0200
Subject: [PATCH 06/25] moved release notes for `ctime` and `localtime`

---
 clang-tools-extra/docs/ReleaseNotes.rst | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/clang-tools-extra/docs/ReleaseNotes.rst b/clang-tools-extra/docs/ReleaseNotes.rst
index 42ddb3c1b76c87..2c9a9bad5dfc15 100644
--- a/clang-tools-extra/docs/ReleaseNotes.rst
+++ b/clang-tools-extra/docs/ReleaseNotes.rst
@@ -97,8 +97,6 @@ The improvements are...
 Improvements to clang-tidy
 --------------------------
 
-- Added `ctime` and `localtime` to clang-tidy.
-
 - Improved :program:`run-clang-tidy.py` script. Fixed minor shutdown noise
   happening on certain platforms when interrupting the script.
 
@@ -115,6 +113,8 @@ New check aliases
 Changes in existing checks
 ^^^^^^^^^^^^^^^^^^^^^^^^^^
 
+- Added `ctime` and `localtime` to clang-tidy.
+
 - Improved :doc:`bugprone-casting-through-void
   <clang-tidy/checks/bugprone/casting-through-void>` check to suggest replacing
   the offending code with ``reinterpret_cast``, to more clearly express intent.

>From b6631f22971c5aad722f997308a02d61822752c0 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?=D0=97=D0=B8=D1=88=D0=B0=D0=BD=20=D0=9C=D0=B8=D1=80=D0=B7?=
 =?UTF-8?q?=D0=B0?= <zmirza at tutanota.de>
Date: Mon, 30 Sep 2024 17:15:48 +0200
Subject: [PATCH 07/25] updated release notes for `ctime` and `localtime`

---
 clang-tools-extra/docs/ReleaseNotes.rst | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/clang-tools-extra/docs/ReleaseNotes.rst b/clang-tools-extra/docs/ReleaseNotes.rst
index 2c9a9bad5dfc15..f5e7eb781b6033 100644
--- a/clang-tools-extra/docs/ReleaseNotes.rst
+++ b/clang-tools-extra/docs/ReleaseNotes.rst
@@ -113,7 +113,8 @@ New check aliases
 Changes in existing checks
 ^^^^^^^^^^^^^^^^^^^^^^^^^^
 
-- Added `ctime` and `localtime` to clang-tidy.
+- New unsafe functions checks :doc:`bugprone-unsafe-functions-check`
+  <clang-tidy/bugprone/UnsafeFunctionsCheck.cpp> were added to clang-tidy.
 
 - Improved :doc:`bugprone-casting-through-void
   <clang-tidy/checks/bugprone/casting-through-void>` check to suggest replacing

>From b54d08b8c58ddf300effa5a73c678d09b0c545f4 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?=D0=97=D0=B8=D1=88=D0=B0=D0=BD=20=D0=9C=D0=B8=D1=80=D0=B7?=
 =?UTF-8?q?=D0=B0?= <zmirza at tutanota.de>
Date: Mon, 30 Sep 2024 17:45:33 +0200
Subject: [PATCH 08/25] added `ctime_r` and `localtime_r` to documentation

---
 .../docs/clang-tidy/checks/bugprone/unsafe-functions.rst       | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/clang-tools-extra/docs/clang-tidy/checks/bugprone/unsafe-functions.rst b/clang-tools-extra/docs/clang-tidy/checks/bugprone/unsafe-functions.rst
index fb070627e31b1d..0199e63d89152c 100644
--- a/clang-tools-extra/docs/clang-tidy/checks/bugprone/unsafe-functions.rst
+++ b/clang-tools-extra/docs/clang-tidy/checks/bugprone/unsafe-functions.rst
@@ -34,7 +34,8 @@ following functions:
 ``vsnprintf``, ``vsprintf``, ``vsscanf``, ``vswprintf``, ``vswscanf``,
 ``vwprintf``, ``vwscanf``, ``wcrtomb``, ``wcscat``, ``wcscpy``,
 ``wcslen``, ``wcsncat``, ``wcsncpy``, ``wcsrtombs``, ``wcstok``, ``wcstombs``,
-``wctomb``, ``wmemcpy``, ``wmemmove``, ``wprintf``, ``wscanf``.
+``wctomb``, ``wmemcpy``, ``wmemmove``, ``wprintf``, ``wscanf``. ``ctime_r``,
+``localtime_r``
 
 If *Annex K.* is not available, replacements are suggested only for the
 following functions from the previous list:

>From 9d38467f6783512e171046396145f42eb8bbbcf0 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?=D0=97=D0=B8=D1=88=D0=B0=D0=BD=20=D0=9C=D0=B8=D1=80=D0=B7?=
 =?UTF-8?q?=D0=B0?= <zmirza at tutanota.de>
Date: Mon, 30 Sep 2024 17:45:57 +0200
Subject: [PATCH 09/25] updated release notes for `ctime` and `localtime`

---
 clang-tools-extra/docs/ReleaseNotes.rst | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/clang-tools-extra/docs/ReleaseNotes.rst b/clang-tools-extra/docs/ReleaseNotes.rst
index f5e7eb781b6033..ae0833509f4c3e 100644
--- a/clang-tools-extra/docs/ReleaseNotes.rst
+++ b/clang-tools-extra/docs/ReleaseNotes.rst
@@ -113,8 +113,9 @@ New check aliases
 Changes in existing checks
 ^^^^^^^^^^^^^^^^^^^^^^^^^^
 
-- New unsafe functions checks :doc:`bugprone-unsafe-functions-check`
-  <clang-tidy/bugprone/UnsafeFunctionsCheck.cpp> were added to clang-tidy.
+- Improved :doc:`bugprone-unsafe-functions-check`
+  `<clang-tidy/checks/bugprone/unsafe-functions>`, added `ctime` and `localtime`
+  to unsafe functions check in clang-tidy.
 
 - Improved :doc:`bugprone-casting-through-void
   <clang-tidy/checks/bugprone/casting-through-void>` check to suggest replacing

>From 9c626e5cee876e551f2ccd56c485e899a4bedf9a Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?=D0=97=D0=B8=D1=88=D0=B0=D0=BD=20=D0=9C=D0=B8=D1=80=D0=B7?=
 =?UTF-8?q?=D0=B0?= <zmirza at tutanota.de>
Date: Mon, 30 Sep 2024 17:48:03 +0200
Subject: [PATCH 10/25] fix: documentation name for unsafe functions check

---
 clang-tools-extra/docs/ReleaseNotes.rst | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/clang-tools-extra/docs/ReleaseNotes.rst b/clang-tools-extra/docs/ReleaseNotes.rst
index ae0833509f4c3e..a0f78bbbf4c284 100644
--- a/clang-tools-extra/docs/ReleaseNotes.rst
+++ b/clang-tools-extra/docs/ReleaseNotes.rst
@@ -113,7 +113,7 @@ New check aliases
 Changes in existing checks
 ^^^^^^^^^^^^^^^^^^^^^^^^^^
 
-- Improved :doc:`bugprone-unsafe-functions-check`
+- Improved :doc:`bugprone-unsafe-functions`
   `<clang-tidy/checks/bugprone/unsafe-functions>`, added `ctime` and `localtime`
   to unsafe functions check in clang-tidy.
 

>From 0ecd051dc86fcb1f6714940b267d0fc8f1c75d2f Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?=D0=97=D0=B8=D1=88=D0=B0=D0=BD=20=D0=9C=D0=B8=D1=80=D0=B7?=
 =?UTF-8?q?=D0=B0?= <zmirza at tutanota.de>
Date: Mon, 30 Sep 2024 17:49:35 +0200
Subject: [PATCH 11/25] fix: release notes for `ctime` and `localtime`

---
 clang-tools-extra/docs/ReleaseNotes.rst | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/clang-tools-extra/docs/ReleaseNotes.rst b/clang-tools-extra/docs/ReleaseNotes.rst
index a0f78bbbf4c284..682e0029f1f612 100644
--- a/clang-tools-extra/docs/ReleaseNotes.rst
+++ b/clang-tools-extra/docs/ReleaseNotes.rst
@@ -113,8 +113,8 @@ New check aliases
 Changes in existing checks
 ^^^^^^^^^^^^^^^^^^^^^^^^^^
 
-- Improved :doc:`bugprone-unsafe-functions`
-  `<clang-tidy/checks/bugprone/unsafe-functions>`, added `ctime` and `localtime`
+- Improved :doc:`bugprone-unsafe-functions
+  <clang-tidy/checks/bugprone/unsafe-functions>`, added `ctime` and `localtime`
   to unsafe functions check in clang-tidy.
 
 - Improved :doc:`bugprone-casting-through-void

>From bf5910164bfdc02b44e463095465e19f7b03b48b Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?=D0=97=D0=B8=D1=88=D0=B0=D0=BD=20=D0=9C=D0=B8=D1=80=D0=B7?=
 =?UTF-8?q?=D0=B0?= <zmirza at tutanota.de>
Date: Mon, 30 Sep 2024 17:59:46 +0200
Subject: [PATCH 12/25] release notes should be in alphabetical order

---
 clang-tools-extra/docs/ReleaseNotes.rst | 8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/clang-tools-extra/docs/ReleaseNotes.rst b/clang-tools-extra/docs/ReleaseNotes.rst
index 682e0029f1f612..50eaf0a1b4b15e 100644
--- a/clang-tools-extra/docs/ReleaseNotes.rst
+++ b/clang-tools-extra/docs/ReleaseNotes.rst
@@ -113,10 +113,6 @@ New check aliases
 Changes in existing checks
 ^^^^^^^^^^^^^^^^^^^^^^^^^^
 
-- Improved :doc:`bugprone-unsafe-functions
-  <clang-tidy/checks/bugprone/unsafe-functions>`, added `ctime` and `localtime`
-  to unsafe functions check in clang-tidy.
-
 - Improved :doc:`bugprone-casting-through-void
   <clang-tidy/checks/bugprone/casting-through-void>` check to suggest replacing
   the offending code with ``reinterpret_cast``, to more clearly express intent.
@@ -143,6 +139,10 @@ Changes in existing checks
   `bsl::optional` and `bdlb::NullableValue` from
   <https://github.com/bloomberg/bde>_.
 
+- Improved :doc:`bugprone-unsafe-functions
+  <clang-tidy/checks/bugprone/unsafe-functions>`, added `ctime` and `localtime`
+  to unsafe functions check in clang-tidy.
+
 - Improved :doc:`bugprone-unsafe-functions
   <clang-tidy/checks/bugprone/unsafe-functions>` check to allow specifying
   additional functions to match.

>From 4772cfe40ce50164ce1685f4e7d0ececaee6351a Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?=D0=97=D0=B8=D1=88=D0=B0=D0=BD=20=D0=9C=D0=B8=D1=80=D0=B7?=
 =?UTF-8?q?=D0=B0?= <zmirza at tutanota.de>
Date: Mon, 30 Sep 2024 18:00:54 +0200
Subject: [PATCH 13/25] updated release notes

---
 clang-tools-extra/docs/ReleaseNotes.rst | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/clang-tools-extra/docs/ReleaseNotes.rst b/clang-tools-extra/docs/ReleaseNotes.rst
index 50eaf0a1b4b15e..f4fce10ae71b8e 100644
--- a/clang-tools-extra/docs/ReleaseNotes.rst
+++ b/clang-tools-extra/docs/ReleaseNotes.rst
@@ -140,8 +140,8 @@ Changes in existing checks
   <https://github.com/bloomberg/bde>_.
 
 - Improved :doc:`bugprone-unsafe-functions
-  <clang-tidy/checks/bugprone/unsafe-functions>`, added `ctime` and `localtime`
-  to unsafe functions check in clang-tidy.
+  <clang-tidy/checks/bugprone/unsafe-functions>` by adding ``ctime`` and
+  ``localtime`` functions.
 
 - Improved :doc:`bugprone-unsafe-functions
   <clang-tidy/checks/bugprone/unsafe-functions>` check to allow specifying

>From 72952bb1d968d57e6c7d254d590d24f9f178058e Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?=D0=97=D0=B8=D1=88=D0=B0=D0=BD=20=D0=9C=D0=B8=D1=80=D0=B7?=
 =?UTF-8?q?=D0=B0?= <zmirza at tutanota.de>
Date: Mon, 30 Sep 2024 18:29:12 +0200
Subject: [PATCH 14/25] fix: function for unsafe functions check

---
 .../clang-tidy/bugprone/UnsafeFunctionsCheck.cpp              | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/clang-tools-extra/clang-tidy/bugprone/UnsafeFunctionsCheck.cpp b/clang-tools-extra/clang-tidy/bugprone/UnsafeFunctionsCheck.cpp
index f058e5ae40680f..106e6c13eb00f5 100644
--- a/clang-tools-extra/clang-tidy/bugprone/UnsafeFunctionsCheck.cpp
+++ b/clang-tools-extra/clang-tidy/bugprone/UnsafeFunctionsCheck.cpp
@@ -50,8 +50,8 @@ static StringRef getReplacementFor(StringRef FunctionName,
     StringRef AnnexKReplacementFunction =
         StringSwitch<StringRef>(FunctionName)
             .Cases("asctime", "asctime_r", "asctime_s")
-            .Cases("ctime", "ctime_r")
-            .Cases("localtime", "localtime_r")
+            .Case("ctime", "ctime_r")
+            .Case("localtime", "localtime_r")
             .Case("gets", "gets_s")
             .Default({});
     if (!AnnexKReplacementFunction.empty())

>From d1e26986b87a964b94bd31869306496e80d46472 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?=D0=97=D0=B8=D1=88=D0=B0=D0=BD=20=D0=9C=D0=B8=D1=80=D0=B7?=
 =?UTF-8?q?=D0=B0?= <zmirza at tutanota.de>
Date: Mon, 30 Sep 2024 18:40:23 +0200
Subject: [PATCH 15/25] add `ctime` and `localtime` to standard library checks

---
 clang-tools-extra/clang-tidy/bugprone/UnsafeFunctionsCheck.cpp | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/clang-tools-extra/clang-tidy/bugprone/UnsafeFunctionsCheck.cpp b/clang-tools-extra/clang-tidy/bugprone/UnsafeFunctionsCheck.cpp
index 106e6c13eb00f5..e5fdc8b1f452a3 100644
--- a/clang-tools-extra/clang-tidy/bugprone/UnsafeFunctionsCheck.cpp
+++ b/clang-tools-extra/clang-tidy/bugprone/UnsafeFunctionsCheck.cpp
@@ -62,6 +62,8 @@ static StringRef getReplacementFor(StringRef FunctionName,
   // should be matched and suggested.
   return StringSwitch<StringRef>(FunctionName)
       .Cases("asctime", "asctime_r", "strftime")
+      .Case("ctime", "ctime_r")
+      .Case("localtime", "localtime_r")
       .Case("gets", "fgets")
       .Case("rewind", "fseek")
       .Case("setbuf", "setvbuf");

>From 6e57fe468d3862fcbd3f2456e4674dceb20e7453 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?=D0=97=D0=B8=D1=88=D0=B0=D0=BD=20=D0=9C=D0=B8=D1=80=D0=B7?=
 =?UTF-8?q?=D0=B0?= <zmirza at tutanota.de>
Date: Mon, 30 Sep 2024 18:42:33 +0200
Subject: [PATCH 16/25] added `ctime` and `localtime` to bounds checking checks

---
 .../clang-tidy/bugprone/UnsafeFunctionsCheck.cpp              | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/clang-tools-extra/clang-tidy/bugprone/UnsafeFunctionsCheck.cpp b/clang-tools-extra/clang-tidy/bugprone/UnsafeFunctionsCheck.cpp
index e5fdc8b1f452a3..b283e7f82a231b 100644
--- a/clang-tools-extra/clang-tidy/bugprone/UnsafeFunctionsCheck.cpp
+++ b/clang-tools-extra/clang-tidy/bugprone/UnsafeFunctionsCheck.cpp
@@ -94,8 +94,8 @@ static StringRef getReplacementForAdditional(StringRef FunctionName,
 /// safer alternative.
 static StringRef getRationaleFor(StringRef FunctionName) {
   return StringSwitch<StringRef>(FunctionName)
-      .Cases("asctime", "asctime_r", "ctime",
-             "is not bounds-checking and non-reentrant")
+      .Cases("asctime", "asctime_r", "ctime", "ctime_r", "localtime",
+             "localtime_r", "is not bounds-checking and non-reentrant")
       .Cases("bcmp", "bcopy", "bzero", "is deprecated")
       .Cases("fopen", "freopen", "has no exclusive access to the opened file")
       .Case("gets", "is insecure, was deprecated and removed in C11 and C++14")

>From ef0d8e2b562ee0968ee4691a0fb0c784da618036 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?=D0=97=D0=B8=D1=88=D0=B0=D0=BD=20=D0=9C=D0=B8=D1=80=D0=B7?=
 =?UTF-8?q?=D0=B0?= <zmirza at tutanota.de>
Date: Mon, 30 Sep 2024 18:45:04 +0200
Subject: [PATCH 17/25] added ctime and localtime to functions list

---
 .../clang-tidy/bugprone/UnsafeFunctionsCheck.cpp              | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/clang-tools-extra/clang-tidy/bugprone/UnsafeFunctionsCheck.cpp b/clang-tools-extra/clang-tidy/bugprone/UnsafeFunctionsCheck.cpp
index b283e7f82a231b..e6b60d1eb411fa 100644
--- a/clang-tools-extra/clang-tidy/bugprone/UnsafeFunctionsCheck.cpp
+++ b/clang-tools-extra/clang-tidy/bugprone/UnsafeFunctionsCheck.cpp
@@ -228,7 +228,9 @@ void UnsafeFunctionsCheck::registerMatchers(MatchFinder *Finder) {
 
     // Matching functions with replacements without Annex K.
     auto FunctionNamesMatcher =
-        hasAnyName("::asctime", "asctime_r", "::gets", "::rewind", "::setbuf");
+        hasAnyName("::asctime", "asctime_r", "::ctime", "ctime_r",
+                   "::localtime", "localtime_r", "::gets", "::rewind",
+                   "::setbuf");
     Finder->addMatcher(
         declRefExpr(
             to(functionDecl(FunctionNamesMatcher).bind(FunctionNamesId)))

>From 43619ca51a041ac58cda2b1950e4055047c579b0 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?=D0=97=D0=B8=D1=88=D0=B0=D0=BD=20=D0=9C=D0=B8=D1=80=D0=B7?=
 =?UTF-8?q?=D0=B0?= <zmirza at tutanota.de>
Date: Mon, 30 Sep 2024 18:51:15 +0200
Subject: [PATCH 18/25] format code with clang-format

---
 .../clang-tidy/bugprone/UnsafeFunctionsCheck.cpp           | 7 +++----
 1 file changed, 3 insertions(+), 4 deletions(-)

diff --git a/clang-tools-extra/clang-tidy/bugprone/UnsafeFunctionsCheck.cpp b/clang-tools-extra/clang-tidy/bugprone/UnsafeFunctionsCheck.cpp
index e6b60d1eb411fa..c4bdda55808d1e 100644
--- a/clang-tools-extra/clang-tidy/bugprone/UnsafeFunctionsCheck.cpp
+++ b/clang-tools-extra/clang-tidy/bugprone/UnsafeFunctionsCheck.cpp
@@ -227,10 +227,9 @@ void UnsafeFunctionsCheck::registerMatchers(MatchFinder *Finder) {
     }
 
     // Matching functions with replacements without Annex K.
-    auto FunctionNamesMatcher =
-        hasAnyName("::asctime", "asctime_r", "::ctime", "ctime_r",
-                   "::localtime", "localtime_r", "::gets", "::rewind",
-                   "::setbuf");
+    auto FunctionNamesMatcher = hasAnyName(
+        "::asctime", "asctime_r", "::ctime", "ctime_r", "::localtime",
+        "localtime_r", "::gets", "::rewind", "::setbuf");
     Finder->addMatcher(
         declRefExpr(
             to(functionDecl(FunctionNamesMatcher).bind(FunctionNamesId)))

>From 8b6931dc25ab882a129616fe9c3c7be07272f3e6 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?=D0=97=D0=B8=D1=88=D0=B0=D0=BD=20=D0=9C=D0=B8=D1=80=D0=B7?=
 =?UTF-8?q?=D0=B0?= <zmirza at tutanota.de>
Date: Mon, 30 Sep 2024 19:23:14 +0200
Subject: [PATCH 19/25] fix: tests

---
 .../clang-tidy/checkers/bugprone/unsafe-functions.c  | 12 ++++++++++++
 1 file changed, 12 insertions(+)

diff --git a/clang-tools-extra/test/clang-tidy/checkers/bugprone/unsafe-functions.c b/clang-tools-extra/test/clang-tidy/checkers/bugprone/unsafe-functions.c
index 0409dd6bfcaa3d..71e1db7672b244 100644
--- a/clang-tools-extra/test/clang-tidy/checkers/bugprone/unsafe-functions.c
+++ b/clang-tools-extra/test/clang-tidy/checkers/bugprone/unsafe-functions.c
@@ -50,6 +50,8 @@ void f1w(wchar_t *S) {
 
 struct tm;
 char *asctime(const struct tm *TimePtr);
+char *ctime(const struct tm *TimePtr);
+char *localtime(const struct tm *tm);
 
 void f2(const struct tm *Time) {
   asctime(Time);
@@ -57,6 +59,16 @@ void f2(const struct tm *Time) {
   // CHECK-MESSAGES-WITH-ANNEX-K-CERT-ONLY: :[[@LINE-2]]:3: warning: function 'asctime' is not bounds-checking and non-reentrant; 'asctime_s' should be used instead
   // CHECK-MESSAGES-WITHOUT-ANNEX-K:        :[[@LINE-3]]:3: warning: function 'asctime' is not bounds-checking and non-reentrant; 'strftime' should be used instead
 
+  ctime(Time);
+  // CHECK-MESSAGES-WITH-ANNEX-K:           :[[@LINE-1]]:3: warning: function 'asctime' is not bounds-checking and non-reentrant; 'ctime_r' should be used instead
+  // CHECK-MESSAGES-WITH-ANNEX-K-CERT-ONLY: :[[@LINE-2]]:3: warning: function 'ctime' is not bounds-checking and non-reentrant; 'ctime_r' should be used instead
+  // CHECK-MESSAGES-WITHOUT-ANNEX-K:        :[[@LINE-3]]:3: warning: function 'ctime' is not bounds-checking and non-reentrant; 'strftime' should be used instead
+
+  localtime(Time);
+  // CHECK-MESSAGES-WITH-ANNEX-K:           :[[@LINE-1]]:3: warning: function 'asctime' is not bounds-checking and non-reentrant; 'localtime_r' should be used instead
+  // CHECK-MESSAGES-WITH-ANNEX-K-CERT-ONLY: :[[@LINE-2]]:3: warning: function 'localtime' is not bounds-checking and non-reentrant; 'localtime_r' should be used instead
+  // CHECK-MESSAGES-WITHOUT-ANNEX-K:        :[[@LINE-3]]:3: warning: function 'localtime' is not bounds-checking and non-reentrant; 'strftime' should be used instead
+
   char *(*F1)(const struct tm *) = asctime;
   // CHECK-MESSAGES-WITH-ANNEX-K:           :[[@LINE-1]]:36: warning: function 'asctime' is not bounds-checking and non-reentrant; 'asctime_s' should be used instead
   // CHECK-MESSAGES-WITH-ANNEX-K-CERT-ONLY: :[[@LINE-2]]:36: warning: function 'asctime' is not bounds-checking and non-reentrant; 'asctime_s' should be used instead

>From 518112ee6f16c3eaafe1a5d44838b7e3d15d74c0 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?=D0=97=D0=B8=D1=88=D0=B0=D0=BD=20=D0=9C=D0=B8=D1=80=D0=B7?=
 =?UTF-8?q?=D0=B0?= <zmirza at tutanota.de>
Date: Mon, 30 Sep 2024 19:26:41 +0200
Subject: [PATCH 20/25] fix: tests

---
 .../checkers/bugprone/unsafe-functions.c      | 24 +++++++++++++++++--
 1 file changed, 22 insertions(+), 2 deletions(-)

diff --git a/clang-tools-extra/test/clang-tidy/checkers/bugprone/unsafe-functions.c b/clang-tools-extra/test/clang-tidy/checkers/bugprone/unsafe-functions.c
index 71e1db7672b244..635bf626677178 100644
--- a/clang-tools-extra/test/clang-tidy/checkers/bugprone/unsafe-functions.c
+++ b/clang-tools-extra/test/clang-tidy/checkers/bugprone/unsafe-functions.c
@@ -60,12 +60,12 @@ void f2(const struct tm *Time) {
   // CHECK-MESSAGES-WITHOUT-ANNEX-K:        :[[@LINE-3]]:3: warning: function 'asctime' is not bounds-checking and non-reentrant; 'strftime' should be used instead
 
   ctime(Time);
-  // CHECK-MESSAGES-WITH-ANNEX-K:           :[[@LINE-1]]:3: warning: function 'asctime' is not bounds-checking and non-reentrant; 'ctime_r' should be used instead
+  // CHECK-MESSAGES-WITH-ANNEX-K:           :[[@LINE-1]]:3: warning: function 'ctime' is not bounds-checking and non-reentrant; 'ctime_r' should be used instead
   // CHECK-MESSAGES-WITH-ANNEX-K-CERT-ONLY: :[[@LINE-2]]:3: warning: function 'ctime' is not bounds-checking and non-reentrant; 'ctime_r' should be used instead
   // CHECK-MESSAGES-WITHOUT-ANNEX-K:        :[[@LINE-3]]:3: warning: function 'ctime' is not bounds-checking and non-reentrant; 'strftime' should be used instead
 
   localtime(Time);
-  // CHECK-MESSAGES-WITH-ANNEX-K:           :[[@LINE-1]]:3: warning: function 'asctime' is not bounds-checking and non-reentrant; 'localtime_r' should be used instead
+  // CHECK-MESSAGES-WITH-ANNEX-K:           :[[@LINE-1]]:3: warning: function 'localtime' is not bounds-checking and non-reentrant; 'localtime_r' should be used instead
   // CHECK-MESSAGES-WITH-ANNEX-K-CERT-ONLY: :[[@LINE-2]]:3: warning: function 'localtime' is not bounds-checking and non-reentrant; 'localtime_r' should be used instead
   // CHECK-MESSAGES-WITHOUT-ANNEX-K:        :[[@LINE-3]]:3: warning: function 'localtime' is not bounds-checking and non-reentrant; 'strftime' should be used instead
 
@@ -78,6 +78,26 @@ void f2(const struct tm *Time) {
   // CHECK-MESSAGES-WITH-ANNEX-K:           :[[@LINE-1]]:37: warning: function 'asctime' is not bounds-checking and non-reentrant; 'asctime_s' should be used instead
   // CHECK-MESSAGES-WITH-ANNEX-K-CERT-ONLY: :[[@LINE-2]]:37: warning: function 'asctime' is not bounds-checking and non-reentrant; 'asctime_s' should be used instead
   // CHECK-MESSAGES-WITHOUT-ANNEX-K:        :[[@LINE-3]]:37: warning: function 'asctime' is not bounds-checking and non-reentrant; 'strftime' should be used instead
+
+  struct tm *(*F1)(const struct tm *) = ctime;
+  // CHECK-MESSAGES-WITH-ANNEX-K:           :[[@LINE-1]]:36: warning: function 'ctime' is not bounds-checking and non-reentrant; 'ctime_r' should be used instead
+  // CHECK-MESSAGES-WITH-ANNEX-K-CERT-ONLY: :[[@LINE-2]]:36: warning: function 'ctime' is not bounds-checking and non-reentrant; 'ctime_r' should be used instead
+  // CHECK-MESSAGES-WITHOUT-ANNEX-K:        :[[@LINE-3]]:36: warning: function 'ctime' is not bounds-checking and non-reentrant; 'strftime' should be used instead
+
+  struct tm *(*F2)(const struct tm *) = &ctime;
+  // CHECK-MESSAGES-WITH-ANNEX-K:           :[[@LINE-1]]:37: warning: function 'ctime' is not bounds-checking and non-reentrant; 'ctime_r' should be used instead
+  // CHECK-MESSAGES-WITH-ANNEX-K-CERT-ONLY: :[[@LINE-2]]:37: warning: function 'ctime' is not bounds-checking and non-reentrant; 'ctime_r' should be used instead
+  // CHECK-MESSAGES-WITHOUT-ANNEX-K:        :[[@LINE-3]]:37: warning: function 'ctime' is not bounds-checking and non-reentrant; 'strftime' should be used instead
+
+  struct tm *(*F1)(const struct tm *) = localtime;
+  // CHECK-MESSAGES-WITH-ANNEX-K:           :[[@LINE-1]]:36: warning: function 'ctime' is not bounds-checking and non-reentrant; 'localtime_r' should be used instead
+  // CHECK-MESSAGES-WITH-ANNEX-K-CERT-ONLY: :[[@LINE-2]]:36: warning: function 'ctime' is not bounds-checking and non-reentrant; 'localtime_r' should be used instead
+  // CHECK-MESSAGES-WITHOUT-ANNEX-K:        :[[@LINE-3]]:36: warning: function 'ctime' is not bounds-checking and non-reentrant; 'strftime' should be used instead
+
+  struct tm *(*F2)(const struct tm *) = &localtime;
+  // CHECK-MESSAGES-WITH-ANNEX-K:           :[[@LINE-1]]:37: warning: function 'localtime' is not bounds-checking and non-reentrant; 'localtime_r' should be used instead
+  // CHECK-MESSAGES-WITH-ANNEX-K-CERT-ONLY: :[[@LINE-2]]:37: warning: function 'localtime' is not bounds-checking and non-reentrant; 'localtime_r' should be used instead
+  // CHECK-MESSAGES-WITHOUT-ANNEX-K:        :[[@LINE-3]]:37: warning: function 'localtime' is not bounds-checking and non-reentrant; 'strftime' should be used instead
 }
 
 typedef void *FILE;

>From f4864b89d73ad0b8350454d954b21624f93ce432 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?=D0=97=D0=B8=D1=88=D0=B0=D0=BD=20=D0=9C=D0=B8=D1=80=D0=B7?=
 =?UTF-8?q?=D0=B0?= <zmirza at tutanota.de>
Date: Mon, 30 Sep 2024 19:30:34 +0200
Subject: [PATCH 21/25] fix: tests for `ctime`

---
 .../test/clang-tidy/checkers/bugprone/unsafe-functions.c      | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/clang-tools-extra/test/clang-tidy/checkers/bugprone/unsafe-functions.c b/clang-tools-extra/test/clang-tidy/checkers/bugprone/unsafe-functions.c
index 635bf626677178..6bd70a672b7ea0 100644
--- a/clang-tools-extra/test/clang-tidy/checkers/bugprone/unsafe-functions.c
+++ b/clang-tools-extra/test/clang-tidy/checkers/bugprone/unsafe-functions.c
@@ -79,12 +79,12 @@ void f2(const struct tm *Time) {
   // CHECK-MESSAGES-WITH-ANNEX-K-CERT-ONLY: :[[@LINE-2]]:37: warning: function 'asctime' is not bounds-checking and non-reentrant; 'asctime_s' should be used instead
   // CHECK-MESSAGES-WITHOUT-ANNEX-K:        :[[@LINE-3]]:37: warning: function 'asctime' is not bounds-checking and non-reentrant; 'strftime' should be used instead
 
-  struct tm *(*F1)(const struct tm *) = ctime;
+  char *(*F1)(const struct tm *) = ctime;
   // CHECK-MESSAGES-WITH-ANNEX-K:           :[[@LINE-1]]:36: warning: function 'ctime' is not bounds-checking and non-reentrant; 'ctime_r' should be used instead
   // CHECK-MESSAGES-WITH-ANNEX-K-CERT-ONLY: :[[@LINE-2]]:36: warning: function 'ctime' is not bounds-checking and non-reentrant; 'ctime_r' should be used instead
   // CHECK-MESSAGES-WITHOUT-ANNEX-K:        :[[@LINE-3]]:36: warning: function 'ctime' is not bounds-checking and non-reentrant; 'strftime' should be used instead
 
-  struct tm *(*F2)(const struct tm *) = &ctime;
+  char *(*F2)(const struct tm *) = &ctime;
   // CHECK-MESSAGES-WITH-ANNEX-K:           :[[@LINE-1]]:37: warning: function 'ctime' is not bounds-checking and non-reentrant; 'ctime_r' should be used instead
   // CHECK-MESSAGES-WITH-ANNEX-K-CERT-ONLY: :[[@LINE-2]]:37: warning: function 'ctime' is not bounds-checking and non-reentrant; 'ctime_r' should be used instead
   // CHECK-MESSAGES-WITHOUT-ANNEX-K:        :[[@LINE-3]]:37: warning: function 'ctime' is not bounds-checking and non-reentrant; 'strftime' should be used instead

>From 105227dd48b5fc4a96789f2e95248868c566bc57 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?=D0=97=D0=B8=D1=88=D0=B0=D0=BD=20=D0=9C=D0=B8=D1=80=D0=B7?=
 =?UTF-8?q?=D0=B0?= <zmirza at tutanota.de>
Date: Mon, 30 Sep 2024 19:32:16 +0200
Subject: [PATCH 22/25] fix: message for localtime

---
 .../test/clang-tidy/checkers/bugprone/unsafe-functions.c    | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/clang-tools-extra/test/clang-tidy/checkers/bugprone/unsafe-functions.c b/clang-tools-extra/test/clang-tidy/checkers/bugprone/unsafe-functions.c
index 6bd70a672b7ea0..8e3478d365a35f 100644
--- a/clang-tools-extra/test/clang-tidy/checkers/bugprone/unsafe-functions.c
+++ b/clang-tools-extra/test/clang-tidy/checkers/bugprone/unsafe-functions.c
@@ -90,9 +90,9 @@ void f2(const struct tm *Time) {
   // CHECK-MESSAGES-WITHOUT-ANNEX-K:        :[[@LINE-3]]:37: warning: function 'ctime' is not bounds-checking and non-reentrant; 'strftime' should be used instead
 
   struct tm *(*F1)(const struct tm *) = localtime;
-  // CHECK-MESSAGES-WITH-ANNEX-K:           :[[@LINE-1]]:36: warning: function 'ctime' is not bounds-checking and non-reentrant; 'localtime_r' should be used instead
-  // CHECK-MESSAGES-WITH-ANNEX-K-CERT-ONLY: :[[@LINE-2]]:36: warning: function 'ctime' is not bounds-checking and non-reentrant; 'localtime_r' should be used instead
-  // CHECK-MESSAGES-WITHOUT-ANNEX-K:        :[[@LINE-3]]:36: warning: function 'ctime' is not bounds-checking and non-reentrant; 'strftime' should be used instead
+  // CHECK-MESSAGES-WITH-ANNEX-K:           :[[@LINE-1]]:36: warning: function 'localtime' is not bounds-checking and non-reentrant; 'localtime_r' should be used instead
+  // CHECK-MESSAGES-WITH-ANNEX-K-CERT-ONLY: :[[@LINE-2]]:36: warning: function 'localtime' is not bounds-checking and non-reentrant; 'localtime_r' should be used instead
+  // CHECK-MESSAGES-WITHOUT-ANNEX-K:        :[[@LINE-3]]:36: warning: function 'localtime' is not bounds-checking and non-reentrant; 'strftime' should be used instead
 
   struct tm *(*F2)(const struct tm *) = &localtime;
   // CHECK-MESSAGES-WITH-ANNEX-K:           :[[@LINE-1]]:37: warning: function 'localtime' is not bounds-checking and non-reentrant; 'localtime_r' should be used instead

>From d8765571f6ea723efe89f7e85740e2661d4808c5 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?=D0=97=D0=B8=D1=88=D0=B0=D0=BD=20=D0=9C=D0=B8=D1=80=D0=B7?=
 =?UTF-8?q?=D0=B0?= <zmirza at tutanota.de>
Date: Mon, 30 Sep 2024 20:06:42 +0200
Subject: [PATCH 23/25] fix: tests for ctime and localtime

---
 .../checkers/bugprone/unsafe-functions.c      | 42 ++++---------------
 1 file changed, 8 insertions(+), 34 deletions(-)

diff --git a/clang-tools-extra/test/clang-tidy/checkers/bugprone/unsafe-functions.c b/clang-tools-extra/test/clang-tidy/checkers/bugprone/unsafe-functions.c
index 8e3478d365a35f..9d61836468b24c 100644
--- a/clang-tools-extra/test/clang-tidy/checkers/bugprone/unsafe-functions.c
+++ b/clang-tools-extra/test/clang-tidy/checkers/bugprone/unsafe-functions.c
@@ -50,8 +50,6 @@ void f1w(wchar_t *S) {
 
 struct tm;
 char *asctime(const struct tm *TimePtr);
-char *ctime(const struct tm *TimePtr);
-char *localtime(const struct tm *tm);
 
 void f2(const struct tm *Time) {
   asctime(Time);
@@ -59,16 +57,6 @@ void f2(const struct tm *Time) {
   // CHECK-MESSAGES-WITH-ANNEX-K-CERT-ONLY: :[[@LINE-2]]:3: warning: function 'asctime' is not bounds-checking and non-reentrant; 'asctime_s' should be used instead
   // CHECK-MESSAGES-WITHOUT-ANNEX-K:        :[[@LINE-3]]:3: warning: function 'asctime' is not bounds-checking and non-reentrant; 'strftime' should be used instead
 
-  ctime(Time);
-  // CHECK-MESSAGES-WITH-ANNEX-K:           :[[@LINE-1]]:3: warning: function 'ctime' is not bounds-checking and non-reentrant; 'ctime_r' should be used instead
-  // CHECK-MESSAGES-WITH-ANNEX-K-CERT-ONLY: :[[@LINE-2]]:3: warning: function 'ctime' is not bounds-checking and non-reentrant; 'ctime_r' should be used instead
-  // CHECK-MESSAGES-WITHOUT-ANNEX-K:        :[[@LINE-3]]:3: warning: function 'ctime' is not bounds-checking and non-reentrant; 'strftime' should be used instead
-
-  localtime(Time);
-  // CHECK-MESSAGES-WITH-ANNEX-K:           :[[@LINE-1]]:3: warning: function 'localtime' is not bounds-checking and non-reentrant; 'localtime_r' should be used instead
-  // CHECK-MESSAGES-WITH-ANNEX-K-CERT-ONLY: :[[@LINE-2]]:3: warning: function 'localtime' is not bounds-checking and non-reentrant; 'localtime_r' should be used instead
-  // CHECK-MESSAGES-WITHOUT-ANNEX-K:        :[[@LINE-3]]:3: warning: function 'localtime' is not bounds-checking and non-reentrant; 'strftime' should be used instead
-
   char *(*F1)(const struct tm *) = asctime;
   // CHECK-MESSAGES-WITH-ANNEX-K:           :[[@LINE-1]]:36: warning: function 'asctime' is not bounds-checking and non-reentrant; 'asctime_s' should be used instead
   // CHECK-MESSAGES-WITH-ANNEX-K-CERT-ONLY: :[[@LINE-2]]:36: warning: function 'asctime' is not bounds-checking and non-reentrant; 'asctime_s' should be used instead
@@ -78,26 +66,6 @@ void f2(const struct tm *Time) {
   // CHECK-MESSAGES-WITH-ANNEX-K:           :[[@LINE-1]]:37: warning: function 'asctime' is not bounds-checking and non-reentrant; 'asctime_s' should be used instead
   // CHECK-MESSAGES-WITH-ANNEX-K-CERT-ONLY: :[[@LINE-2]]:37: warning: function 'asctime' is not bounds-checking and non-reentrant; 'asctime_s' should be used instead
   // CHECK-MESSAGES-WITHOUT-ANNEX-K:        :[[@LINE-3]]:37: warning: function 'asctime' is not bounds-checking and non-reentrant; 'strftime' should be used instead
-
-  char *(*F1)(const struct tm *) = ctime;
-  // CHECK-MESSAGES-WITH-ANNEX-K:           :[[@LINE-1]]:36: warning: function 'ctime' is not bounds-checking and non-reentrant; 'ctime_r' should be used instead
-  // CHECK-MESSAGES-WITH-ANNEX-K-CERT-ONLY: :[[@LINE-2]]:36: warning: function 'ctime' is not bounds-checking and non-reentrant; 'ctime_r' should be used instead
-  // CHECK-MESSAGES-WITHOUT-ANNEX-K:        :[[@LINE-3]]:36: warning: function 'ctime' is not bounds-checking and non-reentrant; 'strftime' should be used instead
-
-  char *(*F2)(const struct tm *) = &ctime;
-  // CHECK-MESSAGES-WITH-ANNEX-K:           :[[@LINE-1]]:37: warning: function 'ctime' is not bounds-checking and non-reentrant; 'ctime_r' should be used instead
-  // CHECK-MESSAGES-WITH-ANNEX-K-CERT-ONLY: :[[@LINE-2]]:37: warning: function 'ctime' is not bounds-checking and non-reentrant; 'ctime_r' should be used instead
-  // CHECK-MESSAGES-WITHOUT-ANNEX-K:        :[[@LINE-3]]:37: warning: function 'ctime' is not bounds-checking and non-reentrant; 'strftime' should be used instead
-
-  struct tm *(*F1)(const struct tm *) = localtime;
-  // CHECK-MESSAGES-WITH-ANNEX-K:           :[[@LINE-1]]:36: warning: function 'localtime' is not bounds-checking and non-reentrant; 'localtime_r' should be used instead
-  // CHECK-MESSAGES-WITH-ANNEX-K-CERT-ONLY: :[[@LINE-2]]:36: warning: function 'localtime' is not bounds-checking and non-reentrant; 'localtime_r' should be used instead
-  // CHECK-MESSAGES-WITHOUT-ANNEX-K:        :[[@LINE-3]]:36: warning: function 'localtime' is not bounds-checking and non-reentrant; 'strftime' should be used instead
-
-  struct tm *(*F2)(const struct tm *) = &localtime;
-  // CHECK-MESSAGES-WITH-ANNEX-K:           :[[@LINE-1]]:37: warning: function 'localtime' is not bounds-checking and non-reentrant; 'localtime_r' should be used instead
-  // CHECK-MESSAGES-WITH-ANNEX-K-CERT-ONLY: :[[@LINE-2]]:37: warning: function 'localtime' is not bounds-checking and non-reentrant; 'localtime_r' should be used instead
-  // CHECK-MESSAGES-WITHOUT-ANNEX-K:        :[[@LINE-3]]:37: warning: function 'localtime' is not bounds-checking and non-reentrant; 'strftime' should be used instead
 }
 
 typedef void *FILE;
@@ -137,11 +105,17 @@ void f3(char *S, FILE *F) {
 
 typedef int time_t;
 char *ctime(const time_t *Timer);
+struct tm *localtime(const struct tm *tm);
 
 void f4(const time_t *Timer) {
   ctime(Timer);
-  // CHECK-MESSAGES-WITH-ANNEX-K:           :[[@LINE-1]]:3: warning: function 'ctime' is not bounds-checking and non-reentrant; 'ctime_s' should be used instead
-  // CHECK-MESSAGES-WITH-ANNEX-K-CERT-ONLY: :[[@LINE-2]]:3: warning: function 'ctime' is not bounds-checking and non-reentrant; 'ctime_s' should be used instead
+  // CHECK-MESSAGES-WITH-ANNEX-K:           :[[@LINE-1]]:3: warning: function 'ctime' is not bounds-checking and non-reentrant; 'ctime_r' should be used instead
+  // CHECK-MESSAGES-WITH-ANNEX-K-CERT-ONLY: :[[@LINE-2]]:3: warning: function 'ctime' is not bounds-checking and non-reentrant; 'ctime_r' should be used instead
+  // no-warning WITHOUT-ANNEX-K
+
+  localtime(Time);
+  // CHECK-MESSAGES-WITH-ANNEX-K:           :[[@LINE-1]]:3: warning: function 'localtime' is not bounds-checking and non-reentrant; 'localtime_r' should be used instead
+  // CHECK-MESSAGES-WITH-ANNEX-K-CERT-ONLY: :[[@LINE-2]]:3: warning: function 'localtime' is not bounds-checking and non-reentrant; 'localtime_r' should be used instead
   // no-warning WITHOUT-ANNEX-K
 }
 

>From d5cef8c1ba3f4d900c5af3eba9d66a538d22c2a4 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?=D0=97=D0=B8=D1=88=D0=B0=D0=BD=20=D0=9C=D0=B8=D1=80=D0=B7?=
 =?UTF-8?q?=D0=B0?= <zmirza at tutanota.de>
Date: Mon, 30 Sep 2024 20:08:57 +0200
Subject: [PATCH 24/25] add ctime and localtime safe functions

---
 .../clang-tidy/checkers/bugprone/unsafe-functions.c    | 10 ++++++++++
 1 file changed, 10 insertions(+)

diff --git a/clang-tools-extra/test/clang-tidy/checkers/bugprone/unsafe-functions.c b/clang-tools-extra/test/clang-tidy/checkers/bugprone/unsafe-functions.c
index 9d61836468b24c..040d1b9aeef3c9 100644
--- a/clang-tools-extra/test/clang-tidy/checkers/bugprone/unsafe-functions.c
+++ b/clang-tools-extra/test/clang-tidy/checkers/bugprone/unsafe-functions.c
@@ -161,6 +161,8 @@ void fOptional() {
 typedef int errno_t;
 typedef size_t rsize_t;
 errno_t asctime_s(char *S, rsize_t Maxsize, const struct tm *TimePtr);
+errno_t ctime_r(char *S, rsize_t Maxsize, const struct tm *TimePtr);
+errno_t localtime_r(char *S, rsize_t Maxsize, const struct tm *tm);
 errno_t strcat_s(char *S1, rsize_t S1Max, const char *S2);
 
 void fUsingSafeFunctions(const struct tm *Time, FILE *F) {
@@ -170,6 +172,14 @@ void fUsingSafeFunctions(const struct tm *Time, FILE *F) {
   if (asctime_s(Buf, BUFSIZ, Time) != 0)
     return;
 
+  // no-warning, safe function from annex K is used
+  if (ctime_s(Buf, BUFSIZ, Time) != 0)
+    return;
+
+  // no-warning, safe function from annex K is used
+  if (localtime_s(Buf, BUFSIZ, Time) != 0)
+    return;
+
   // no-warning, safe function from annex K is used
   if (strcat_s(Buf, BUFSIZ, "something") != 0)
     return;

>From 18284985275767e4dfea86ae6b440464e94c3874 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?=D0=97=D0=B8=D1=88=D0=B0=D0=BD=20=D0=9C=D0=B8=D1=80=D0=B7?=
 =?UTF-8?q?=D0=B0?= <zmirza at tutanota.de>
Date: Mon, 30 Sep 2024 20:10:19 +0200
Subject: [PATCH 25/25] fix: localtime_r argument

---
 .../test/clang-tidy/checkers/bugprone/unsafe-functions.c        | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/clang-tools-extra/test/clang-tidy/checkers/bugprone/unsafe-functions.c b/clang-tools-extra/test/clang-tidy/checkers/bugprone/unsafe-functions.c
index 040d1b9aeef3c9..3e77af2a8a5148 100644
--- a/clang-tools-extra/test/clang-tidy/checkers/bugprone/unsafe-functions.c
+++ b/clang-tools-extra/test/clang-tidy/checkers/bugprone/unsafe-functions.c
@@ -162,7 +162,7 @@ typedef int errno_t;
 typedef size_t rsize_t;
 errno_t asctime_s(char *S, rsize_t Maxsize, const struct tm *TimePtr);
 errno_t ctime_r(char *S, rsize_t Maxsize, const struct tm *TimePtr);
-errno_t localtime_r(char *S, rsize_t Maxsize, const struct tm *tm);
+errno_t localtime_r(char *S, rsize_t Maxsize, const struct tm *TimePtr);
 errno_t strcat_s(char *S1, rsize_t S1Max, const char *S2);
 
 void fUsingSafeFunctions(const struct tm *Time, FILE *F) {



More information about the cfe-commits mailing list