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

Зишан Мирза via llvm-commits llvm-commits at lists.llvm.org
Sat Jan 4 03:28:34 PST 2025


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

>From 193e93c52e6a523366470aa45088b434eb5628ef 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: Thu, 26 Dec 2024 08:29:03 +0500
Subject: [PATCH 01/47] [clang-tidy] add `ctime` and `localtime` to
 `clang-tidy`

Closes #107445
---
 .../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 ++++++++-
 4 files changed, 22 insertions(+), 1 deletion(-)

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 c1927180d33976..7a08a5d3beee7a 100644
--- a/clang/lib/Tooling/Inclusions/Stdlib/StdSymbolMap.inc
+++ b/clang/lib/Tooling/Inclusions/Stdlib/StdSymbolMap.inc
@@ -618,6 +618,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 e4d339092a9509e7825a8661a76e74cdeac9f0db 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/47] [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 9f6f3aa985b198b19670a4f5cdee7b118b680b23 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: Thu, 26 Dec 2024 08:30:17 +0500
Subject: [PATCH 03/47] [clang-tidy] add `ctime` and `localtime` to
 `clang-tidy`

add changes to release notes
---
 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 1fd9b6077be5f5..c011824d4f1d71 100644
--- a/clang-tools-extra/docs/ReleaseNotes.rst
+++ b/clang-tools-extra/docs/ReleaseNotes.rst
@@ -111,7 +111,7 @@ Improvements to clang-tidy
 - Improved :program:`clang-tidy`'s `--verify-config` flag by adding support for
   the configuration options of the `Clang Static Analyzer Checks
   <https://clang.llvm.org/docs/analyzer/checkers.html>`_.
-
+- 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 b6cbc9d4aa76595dd6c1eebdb9f9b83b75dfb66f 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/47] [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 b23a597125c60483142eb19f8dea94985ff1dda9 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/47] 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 7a08a5d3beee7a..c1927180d33976 100644
--- a/clang/lib/Tooling/Inclusions/Stdlib/StdSymbolMap.inc
+++ b/clang/lib/Tooling/Inclusions/Stdlib/StdSymbolMap.inc
@@ -618,12 +618,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 c62bbb1d2bf2c2f781f09abecc9b295fdc40fba6 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: Thu, 26 Dec 2024 08:31:14 +0500
Subject: [PATCH 06/47] moved release notes for `ctime` and `localtime`

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

diff --git a/clang-tools-extra/docs/ReleaseNotes.rst b/clang-tools-extra/docs/ReleaseNotes.rst
index c011824d4f1d71..e2892f85b44003 100644
--- a/clang-tools-extra/docs/ReleaseNotes.rst
+++ b/clang-tools-extra/docs/ReleaseNotes.rst
@@ -111,7 +111,9 @@ Improvements to clang-tidy
 - Improved :program:`clang-tidy`'s `--verify-config` flag by adding support for
   the configuration options of the `Clang Static Analyzer Checks
   <https://clang.llvm.org/docs/analyzer/checkers.html>`_.
+
 - 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.
 
@@ -187,6 +189,8 @@ Changes in existing checks
   <clang-tidy/checks/bugprone/branch-clone>` check to improve detection of
   branch clones by now detecting duplicate inner and outer if statements.
 
+- 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 ec0d4b2feb5adab9ba8956837fec7681e5262f0e 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: Thu, 26 Dec 2024 08:31:51 +0500
Subject: [PATCH 07/47] updated release notes for `ctime` and `localtime`

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

diff --git a/clang-tools-extra/docs/ReleaseNotes.rst b/clang-tools-extra/docs/ReleaseNotes.rst
index e2892f85b44003..f543fdac137ea3 100644
--- a/clang-tools-extra/docs/ReleaseNotes.rst
+++ b/clang-tools-extra/docs/ReleaseNotes.rst
@@ -191,6 +191,9 @@ 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
   the offending code with ``reinterpret_cast``, to more clearly express intent.

>From c02eba52eb4ad83d712fb0097b728c14c5e4f994 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/47] 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 694fdc54bd48c2a21addfe4ee5cb8594826ffdf7 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: Thu, 26 Dec 2024 08:32:23 +0500
Subject: [PATCH 09/47] updated release notes for `ctime` and `localtime`

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

diff --git a/clang-tools-extra/docs/ReleaseNotes.rst b/clang-tools-extra/docs/ReleaseNotes.rst
index f543fdac137ea3..224750fe667bf4 100644
--- a/clang-tools-extra/docs/ReleaseNotes.rst
+++ b/clang-tools-extra/docs/ReleaseNotes.rst
@@ -194,6 +194,10 @@ 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
   the offending code with ``reinterpret_cast``, to more clearly express intent.

>From e21494a3cc5020f7488b7375e39cb421d070ec99 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: Thu, 26 Dec 2024 08:34:24 +0500
Subject: [PATCH 10/47] 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 224750fe667bf4..9b34edbf882d7c 100644
--- a/clang-tools-extra/docs/ReleaseNotes.rst
+++ b/clang-tools-extra/docs/ReleaseNotes.rst
@@ -194,8 +194,8 @@ 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`
+- 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 02dbcb1f26870e40676c08ea1aa0123ddfe93d07 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: Thu, 26 Dec 2024 08:34:57 +0500
Subject: [PATCH 11/47] release notes should be in alphabetical order

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

diff --git a/clang-tools-extra/docs/ReleaseNotes.rst b/clang-tools-extra/docs/ReleaseNotes.rst
index 9b34edbf882d7c..2fa24e516c2781 100644
--- a/clang-tools-extra/docs/ReleaseNotes.rst
+++ b/clang-tools-extra/docs/ReleaseNotes.rst
@@ -244,6 +244,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 b0dcfe6bba0035efd2dc12f3aceedecaa3de28b1 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 12/47] 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 2fa24e516c2781..c2425954640da5 100644
--- a/clang-tools-extra/docs/ReleaseNotes.rst
+++ b/clang-tools-extra/docs/ReleaseNotes.rst
@@ -245,8 +245,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 41e9ab531f177b1619e2389c9d4c5ac7569023bf 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 13/47] 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 e6fe973a5341a28f9c896302e392bf35a7749c4d 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 14/47] 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 916a5d4f3ba13d43416cbad8cdd2b18404fab262 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 15/47] 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 7cfffee8919dc26d559336e2e1f59d5d7252e255 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 16/47] 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 64d076541fd2742bf344f155f2383abe336cc571 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 17/47] 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 d466bae9927e179a930806c94af23126756e1e9f 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 18/47] 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 b8de0a45ddd2e0867e2fced75f4e97484dd1d6c9 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 19/47] 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 4781f138796488870818cf3c275e0ca765861dd4 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 20/47] 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 079126e7ebeee4e8ec9b27144f4d33dee341d1b1 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 21/47] 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 c0d5ecebc1806e98f356637901b8da86301c3251 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 22/47] 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 bb63d8cd0ec21e1b64a62850556e7a0cbd9e7568 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 23/47] 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 10468a379768e617632126cdb5469ef4e4925e55 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 24/47] 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) {

>From a5da8a0a1e2622eac5aa74cf7c0ba8809ccec935 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:11:14 +0200
Subject: [PATCH 25/47] use `_r` functions, since `_s` functions are not
 implemented

---
 .../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 3e77af2a8a5148..86b00b504513bf 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
@@ -173,11 +173,11 @@ void fUsingSafeFunctions(const struct tm *Time, FILE *F) {
     return;
 
   // no-warning, safe function from annex K is used
-  if (ctime_s(Buf, BUFSIZ, Time) != 0)
+  if (ctime_r(Buf, BUFSIZ, Time) != 0)
     return;
 
   // no-warning, safe function from annex K is used
-  if (localtime_s(Buf, BUFSIZ, Time) != 0)
+  if (localtime_r(Buf, BUFSIZ, Time) != 0)
     return;
 
   // no-warning, safe function from annex K is used

>From ee9b8c6e1ab8c78260d38378fbfb3c7373147743 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:19:40 +0200
Subject: [PATCH 26/47] safe functions should be used

---
 .../checkers/bugprone/unsafe-functions.c         | 16 ++++++++--------
 1 file changed, 8 insertions(+), 8 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 86b00b504513bf..d5a14c3b16630b 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
@@ -109,13 +109,13 @@ 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_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-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
   // 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
+  // CHECK-MESSAGES-WITH-ANNEX-K:           :[[@LINE-1]]:3: warning: function 'localtime' is not bounds-checking and non-reentrant; 'localtime_s' 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_s' should be used instead
   // no-warning WITHOUT-ANNEX-K
 }
 
@@ -161,8 +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 *TimePtr);
+errno_t ctime_s(char *S, rsize_t Maxsize, const struct tm *TimePtr);
+errno_t localtime_s(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) {
@@ -173,11 +173,11 @@ void fUsingSafeFunctions(const struct tm *Time, FILE *F) {
     return;
 
   // no-warning, safe function from annex K is used
-  if (ctime_r(Buf, BUFSIZ, Time) != 0)
+  if (ctime_s(Buf, BUFSIZ, Time) != 0)
     return;
 
   // no-warning, safe function from annex K is used
-  if (localtime_r(Buf, BUFSIZ, Time) != 0)
+  if (localtime_s(Buf, BUFSIZ, Time) != 0)
     return;
 
   // no-warning, safe function from annex K is used

>From 041b0e743d413bf2ea1986805071f49a41ea0e73 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:41:18 +0200
Subject: [PATCH 27/47] use safe functions

---
 .../clang-tidy/bugprone/UnsafeFunctionsCheck.cpp          | 8 ++++----
 .../test/clang-tidy/checkers/bugprone/unsafe-functions.c  | 6 +++---
 2 files changed, 7 insertions(+), 7 deletions(-)

diff --git a/clang-tools-extra/clang-tidy/bugprone/UnsafeFunctionsCheck.cpp b/clang-tools-extra/clang-tidy/bugprone/UnsafeFunctionsCheck.cpp
index c4bdda55808d1e..322fd82464e798 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")
-            .Case("ctime", "ctime_r")
-            .Case("localtime", "localtime_r")
+            .Cases("ctime", "ctime_r", "ctime_s")
+            .Cases("localtime", "localtime_r", "localtime_s")
             .Case("gets", "gets_s")
             .Default({});
     if (!AnnexKReplacementFunction.empty())
@@ -62,8 +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")
+      .Cases("ctime", "ctime_r", "ctime_s")
+      .Cases("localtime", "localtime_r", "localtime_s")
       .Case("gets", "fgets")
       .Case("rewind", "fseek")
       .Case("setbuf", "setvbuf");
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 d5a14c3b16630b..95eb3613258453 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,10 +162,10 @@ 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_s(char *S, rsize_t Maxsize, const struct tm *TimePtr);
-errno_t localtime_s(char *S, rsize_t Maxsize, const struct tm *TimePtr);
+errno_t localtime_s(struct tm *TimePtr, time_t *Timep);
 errno_t strcat_s(char *S1, rsize_t S1Max, const char *S2);
 
-void fUsingSafeFunctions(const struct tm *Time, FILE *F) {
+void fUsingSafeFunctions(const struct tm *Time, FILE *F, time_t *Timep) {
   char Buf[BUFSIZ] = {0};
 
   // no-warning, safe function from annex K is used
@@ -177,7 +177,7 @@ void fUsingSafeFunctions(const struct tm *Time, FILE *F) {
     return;
 
   // no-warning, safe function from annex K is used
-  if (localtime_s(Buf, BUFSIZ, Time) != 0)
+  if (localtime_s(Time, Timep) != 0)
     return;
 
   // no-warning, safe function from annex K is used

>From a74fc4b149a0fd8447246236513881953e63d416 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 21:24:19 +0200
Subject: [PATCH 28/47] fix: localtime 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 95eb3613258453..0a321f3981be54 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
@@ -113,7 +113,7 @@ void f4(const time_t *Timer) {
   // 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
   // no-warning WITHOUT-ANNEX-K
 
-  localtime(Time);
+  localtime(Timer);
   // CHECK-MESSAGES-WITH-ANNEX-K:           :[[@LINE-1]]:3: warning: function 'localtime' is not bounds-checking and non-reentrant; 'localtime_s' 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_s' should be used instead
   // no-warning WITHOUT-ANNEX-K

>From 4f500807c8e81964390f9b1089804be8d750fc12 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 22:14:51 +0200
Subject: [PATCH 29/47] temporarily use `_r` functions

---
 .../test/clang-tidy/checkers/bugprone/unsafe-functions.c  | 8 ++++----
 1 file changed, 4 insertions(+), 4 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 0a321f3981be54..56f31232c37e39 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
@@ -109,13 +109,13 @@ 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(Timer);
-  // CHECK-MESSAGES-WITH-ANNEX-K:           :[[@LINE-1]]:3: warning: function 'localtime' is not bounds-checking and non-reentrant; 'localtime_s' 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_s' 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
   // no-warning WITHOUT-ANNEX-K
 }
 

>From 666de6055c38311bb2a8a59d98ded984496137ee 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: Tue, 1 Oct 2024 18:41:56 +0200
Subject: [PATCH 30/47] use `_s` functions and add functions for `ctime` and
 `localtime`

---
 .../checkers/bugprone/unsafe-functions.c       | 18 ++++++++++++++----
 1 file changed, 14 insertions(+), 4 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 56f31232c37e39..12e042347b9eb4 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
@@ -109,13 +109,23 @@ 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_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-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
   // no-warning WITHOUT-ANNEX-K
 
   localtime(Timer);
-  // 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-WITH-ANNEX-K:           :[[@LINE-1]]:3: warning: function 'localtime' is not bounds-checking and non-reentrant; 'localtime_s' 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_s' should be used instead
+  // no-warning WITHOUT-ANNEX-K
+
+  char *(*F4)(const struct tm *) = &ctime;
+  // CHECK-MESSAGES-WITH-ANNEX-K:           :[[@LINE-1]]:37: 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]]:37: warning: function 'ctime' is not bounds-checking and non-reentrant; 'ctime_s' should be used instead
+  // no-warning WITHOUT-ANNEX-K
+
+  struct tm *(*F4)(const struct tm *) = &localtime;
+  // CHECK-MESSAGES-WITH-ANNEX-K:           :[[@LINE-1]]:37: warning: function 'localtime' is not bounds-checking and non-reentrant; 'localtime_s' 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_s' should be used instead
   // no-warning WITHOUT-ANNEX-K
 }
 

>From 16535e4443556aa69a7bd70dfc00689261261694 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: Tue, 1 Oct 2024 19:33:20 +0200
Subject: [PATCH 31/47] fix: function names

---
 .../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 12e042347b9eb4..aeab8ad69d4e69 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
@@ -118,12 +118,12 @@ void f4(const time_t *Timer) {
   // CHECK-MESSAGES-WITH-ANNEX-K-CERT-ONLY: :[[@LINE-2]]:3: warning: function 'localtime' is not bounds-checking and non-reentrant; 'localtime_s' should be used instead
   // no-warning WITHOUT-ANNEX-K
 
-  char *(*F4)(const struct tm *) = &ctime;
+  char *(*F1)(const struct tm *) = &ctime;
   // CHECK-MESSAGES-WITH-ANNEX-K:           :[[@LINE-1]]:37: 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]]:37: warning: function 'ctime' is not bounds-checking and non-reentrant; 'ctime_s' should be used instead
   // no-warning WITHOUT-ANNEX-K
 
-  struct tm *(*F4)(const struct tm *) = &localtime;
+  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_s' 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_s' should be used instead
   // no-warning WITHOUT-ANNEX-K

>From 0e7003b5da00e89fb0694683ac704fb3209f9d5e 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: Tue, 1 Oct 2024 20:10:25 +0200
Subject: [PATCH 32/47] fix: tests for clang-tidy

---
 .../checkers/bugprone/unsafe-functions.c      | 38 ++++++++++++-------
 1 file changed, 24 insertions(+), 14 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 aeab8ad69d4e69..cd607f783259db 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
@@ -105,28 +105,38 @@ void f3(char *S, FILE *F) {
 
 typedef int time_t;
 char *ctime(const time_t *Timer);
-struct tm *localtime(const struct tm *tm);
+struct tm *localtime(const time_t *Timer);
 
 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
-  // no-warning WITHOUT-ANNEX-K
+  // CHECK-MESSAGES-WITH-ANNEX-K:           :[[@LINE-1]]:116: 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]]:116: warning: function 'ctime' is not bounds-checking and non-reentrant; 'ctime_s' should be used instead
+  // CHECK-MESSAGES-WITHOUT-ANNEX-K:        :[[@LINE-3]]:116: warning: function 'ctime' is not bounds-checking and non-reentrant; 'strftime' should be used instead
 
   localtime(Timer);
-  // CHECK-MESSAGES-WITH-ANNEX-K:           :[[@LINE-1]]:3: warning: function 'localtime' is not bounds-checking and non-reentrant; 'localtime_s' 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_s' should be used instead
-  // no-warning WITHOUT-ANNEX-K
+  // CHECK-MESSAGES-WITH-ANNEX-K:           :[[@LINE-1]]:116: warning: function 'localtime' is not bounds-checking and non-reentrant; 'localtime_s' should be used instead
+  // CHECK-MESSAGES-WITH-ANNEX-K-CERT-ONLY: :[[@LINE-2]]:116: warning: function 'localtime' is not bounds-checking and non-reentrant; 'localtime_s' should be used instead
+  // CHECK-MESSAGES-WITHOUT-ANNEX-K:        :[[@LINE-3]]:116: warning: function 'localtime' is not bounds-checking and non-reentrant; 'strftime' should be used instead
+
+  char *(*F1)(const time_t *) = ctime;
+  // CHECK-MESSAGES-WITH-ANNEX-K:           :[[@LINE-1]]:36: 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]]:36: warning: function 'ctime' is not bounds-checking and non-reentrant; 'ctime_s' 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 *(*F1)(const struct tm *) = &ctime;
+  char *(*F2)(const time_t *) = &ctime;
   // CHECK-MESSAGES-WITH-ANNEX-K:           :[[@LINE-1]]:37: 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]]:37: warning: function 'ctime' is not bounds-checking and non-reentrant; 'ctime_s' should be used instead
-  // no-warning WITHOUT-ANNEX-K
+  // 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 *(*F4)(const time_t *) = localtime;
+  // CHECK-MESSAGES-WITH-ANNEX-K:           :[[@LINE-1]]:36: warning: function 'localtime' is not bounds-checking and non-reentrant; 'localtime_s' 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_s' 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;
+  struct tm *(*F5)(const time_t *) = &localtime;
   // CHECK-MESSAGES-WITH-ANNEX-K:           :[[@LINE-1]]:37: warning: function 'localtime' is not bounds-checking and non-reentrant; 'localtime_s' 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_s' should be used instead
-  // no-warning WITHOUT-ANNEX-K
+  // CHECK-MESSAGES-WITHOUT-ANNEX-K:        :[[@LINE-3]]:37: warning: function 'localtime' is not bounds-checking and non-reentrant; 'strftime' should be used instead
 }
 
 #define BUFSIZ 128
@@ -171,8 +181,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_s(char *S, rsize_t Maxsize, const struct tm *TimePtr);
-errno_t localtime_s(struct tm *TimePtr, time_t *Timep);
+errno_t ctime_s(char *S, rsize_t Maxsize, const time_t *Timep);
+errno_t localtime_s(const time_t *Timep, 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, time_t *Timep) {
@@ -187,7 +197,7 @@ void fUsingSafeFunctions(const struct tm *Time, FILE *F, time_t *Timep) {
     return;
 
   // no-warning, safe function from annex K is used
-  if (localtime_s(Time, Timep) != 0)
+  if (localtime_s(Timep, BUFSIZ, Time) != 0)
     return;
 
   // no-warning, safe function from annex K is used

>From 888993ef19557150fec22c45dc3d0a9ca26112a2 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: Tue, 1 Oct 2024 21:03:38 +0200
Subject: [PATCH 33/47] temporarily remove localtime

---
 .../checkers/bugprone/unsafe-functions.c      | 31 ++-----------------
 1 file changed, 3 insertions(+), 28 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 cd607f783259db..bb442978420975 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
@@ -109,34 +109,9 @@ struct tm *localtime(const time_t *Timer);
 
 void f4(const time_t *Timer) {
   ctime(Timer);
-  // CHECK-MESSAGES-WITH-ANNEX-K:           :[[@LINE-1]]:116: 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]]:116: warning: function 'ctime' is not bounds-checking and non-reentrant; 'ctime_s' should be used instead
-  // CHECK-MESSAGES-WITHOUT-ANNEX-K:        :[[@LINE-3]]:116: warning: function 'ctime' is not bounds-checking and non-reentrant; 'strftime' should be used instead
-
-  localtime(Timer);
-  // CHECK-MESSAGES-WITH-ANNEX-K:           :[[@LINE-1]]:116: warning: function 'localtime' is not bounds-checking and non-reentrant; 'localtime_s' should be used instead
-  // CHECK-MESSAGES-WITH-ANNEX-K-CERT-ONLY: :[[@LINE-2]]:116: warning: function 'localtime' is not bounds-checking and non-reentrant; 'localtime_s' should be used instead
-  // CHECK-MESSAGES-WITHOUT-ANNEX-K:        :[[@LINE-3]]:116: warning: function 'localtime' is not bounds-checking and non-reentrant; 'strftime' should be used instead
-
-  char *(*F1)(const time_t *) = ctime;
-  // CHECK-MESSAGES-WITH-ANNEX-K:           :[[@LINE-1]]:36: 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]]:36: warning: function 'ctime' is not bounds-checking and non-reentrant; 'ctime_s' 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 time_t *) = &ctime;
-  // CHECK-MESSAGES-WITH-ANNEX-K:           :[[@LINE-1]]:37: 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]]:37: warning: function 'ctime' is not bounds-checking and non-reentrant; 'ctime_s' 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 *(*F4)(const time_t *) = localtime;
-  // CHECK-MESSAGES-WITH-ANNEX-K:           :[[@LINE-1]]:36: warning: function 'localtime' is not bounds-checking and non-reentrant; 'localtime_s' 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_s' 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 *(*F5)(const time_t *) = &localtime;
-  // CHECK-MESSAGES-WITH-ANNEX-K:           :[[@LINE-1]]:37: warning: function 'localtime' is not bounds-checking and non-reentrant; 'localtime_s' 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_s' 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
+  // 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
+  // no-warning WITHOUT-ANNEX-K
 }
 
 #define BUFSIZ 128

>From d2b2e22abcf569df62e5d88121ac6bc84d5a2ceb 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: Tue, 1 Oct 2024 21:04:05 +0200
Subject: [PATCH 34/47] add tests for ctime and localtime

---
 .../Inputs/std-c-library-functions-POSIX.h    |  4 ++-
 clang/test/Analysis/cert/env34-c.c            | 32 +++++++++++++++++--
 .../Analysis/std-c-library-functions-POSIX.c  |  4 ++-
 3 files changed, 36 insertions(+), 4 deletions(-)

diff --git a/clang/test/Analysis/Inputs/std-c-library-functions-POSIX.h b/clang/test/Analysis/Inputs/std-c-library-functions-POSIX.h
index b146068eedb080..16941434ab78e0 100644
--- a/clang/test/Analysis/Inputs/std-c-library-functions-POSIX.h
+++ b/clang/test/Analysis/Inputs/std-c-library-functions-POSIX.h
@@ -174,9 +174,11 @@ int utimensat(int dirfd, const char *pathname, const struct timespec times[2], i
 int utimes(const char *filename, const struct timeval times[2]);
 int nanosleep(const struct timespec *rqtp, struct timespec *rmtp);
 struct tm *localtime(const time_t *tp);
-struct tm *localtime_r(const time_t *restrict timer, struct tm *restrict result);
+struct tm *localtime_r(const time_t *timer, struct tm *result);
+struct tm *localtime_s(const time_t *restrict timer, struct tm *restrict result);
 char *asctime_r(const struct tm *restrict tm, char *restrict buf);
 char *ctime_r(const time_t *timep, char *buf);
+char *ctime_s(char *buf, rsize_t buf_size, const time_t *timep);
 struct tm *gmtime_r(const time_t *restrict timer, struct tm *restrict result);
 struct tm *gmtime(const time_t *tp);
 int clock_gettime(clockid_t clock_id, struct timespec *tp);
diff --git a/clang/test/Analysis/cert/env34-c.c b/clang/test/Analysis/cert/env34-c.c
index ae344a815679ec..0f1dd8707f98f4 100644
--- a/clang/test/Analysis/cert/env34-c.c
+++ b/clang/test/Analysis/cert/env34-c.c
@@ -16,8 +16,8 @@ lconv *localeconv(void);
 typedef struct {
 } tm;
 char *asctime(const tm *timeptr);
-char *ctime(const tm *timeptr);
-struct tm *localtime(struct tm *tm);
+char *ctime(const time_t *time);
+struct tm *localtime(const time_t *time);
 
 int strcmp(const char*, const char*);
 extern void foo(char *e);
@@ -315,6 +315,34 @@ void asctime_test(void) {
   // expected-note at -2{{dereferencing an invalid pointer}}
 }
 
+void ctime_test(void) {
+  const time_t *t;
+  const time_t *tt;
+
+  char* p = ctime(t);
+  // expected-note at -1{{previous function call was here}}
+  char* pp = ctime(tt);
+  // expected-note at -1{{'ctime' call may invalidate the result of the previous 'ctime'}}
+
+  *p;
+  // expected-warning at -1{{dereferencing an invalid pointer}}
+  // expected-note at -2{{dereferencing an invalid pointer}}
+}
+
+void time_test(void) {
+  const time_t *t;
+  const time_t *tt;
+
+  struct tm* p = localtime(t);
+  // expected-note at -1{{previous function call was here}}
+  struct tm* pp = localtime(tt);
+  // expected-note at -1{{'localtime' call may invalidate the result of the previous 'localtime'}}
+
+  *p;
+  // expected-warning at -1{{dereferencing an invalid pointer}}
+  // expected-note at -2{{dereferencing an invalid pointer}}
+}
+
 void localeconv_test1(void) {
   lconv *lc1 = localeconv();
   // expected-note at -1{{previous function call was here}}
diff --git a/clang/test/Analysis/std-c-library-functions-POSIX.c b/clang/test/Analysis/std-c-library-functions-POSIX.c
index b53f3132b86877..872165e542e17e 100644
--- a/clang/test/Analysis/std-c-library-functions-POSIX.c
+++ b/clang/test/Analysis/std-c-library-functions-POSIX.c
@@ -129,9 +129,11 @@
 // CHECK: Loaded summary for: int utimes(const char *filename, const struct timeval times[2])
 // CHECK: Loaded summary for: int nanosleep(const struct timespec *rqtp, struct timespec *rmtp)
 // CHECK: Loaded summary for: struct tm *localtime(const time_t *tp)
-// CHECK: Loaded summary for: struct tm *localtime_r(const time_t *restrict timer, struct tm *restrict result)
+// CHECK: Loaded summary for: struct tm *localtime_r(const time_t *timer, struct tm *result)
+// CHECK: Loaded summary for: struct tm *localtime_s(const time_t *restrict timer, struct tm *restrict result)
 // CHECK: Loaded summary for: char *asctime_r(const struct tm *restrict tm, char *restrict buf)
 // CHECK: Loaded summary for: char *ctime_r(const time_t *timep, char *buf)
+// CHECK: Loaded summary for: char *ctime_s(char *buf, rsize_t buf_size, const time_t *timep)
 // CHECK: Loaded summary for: struct tm *gmtime_r(const time_t *restrict timer, struct tm *restrict result)
 // CHECK: Loaded summary for: struct tm *gmtime(const time_t *tp)
 // CHECK: Loaded summary for: int clock_gettime(clockid_t clock_id, struct timespec *tp)

>From a7f561cc473535b8da06ddf86cde4edc08295791 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: Fri, 4 Oct 2024 20:18:55 +0200
Subject: [PATCH 35/47] update tests for ctime and localtime

---
 .../checks/bugprone/unsafe-functions.rst      |  2 ++
 .../checkers/bugprone/unsafe-functions.c      |  1 -
 .../Checkers/StdLibraryFunctionsChecker.cpp   | 25 +++++++++++++++++--
 .../Inclusions/Stdlib/StdSymbolMap.inc        |  4 +--
 clang/test/Analysis/cert/env34-c.c            |  2 +-
 .../lib/dfsan/libc_ubuntu1404_abilist.txt     |  2 ++
 .../sanitizer_common_interceptors.inc         | 23 +++++++++++++++++
 7 files changed, 53 insertions(+), 6 deletions(-)

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 0199e63d89152c..2b3f4df6001185 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
@@ -41,6 +41,8 @@ If *Annex K.* is not available, replacements are suggested only for the
 following functions from the previous list:
 
  - ``asctime``, ``asctime_r``, suggested replacement: ``strftime``
+ - ``ctime``, ``ctime_r``, suggested replacement: ``ctime_s``
+ - ``localtime``, ``localtime_r``, suggested replacement: ``localtime_s``
  - ``gets``, suggested replacement: ``fgets``
 
 The following functions are always checked, regardless of *Annex K* availability:
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 bb442978420975..bc1e6007201bb2 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
@@ -105,7 +105,6 @@ void f3(char *S, FILE *F) {
 
 typedef int time_t;
 char *ctime(const time_t *Timer);
-struct tm *localtime(const time_t *Timer);
 
 void f4(const time_t *Timer) {
   ctime(Timer);
diff --git a/clang/lib/StaticAnalyzer/Checkers/StdLibraryFunctionsChecker.cpp b/clang/lib/StaticAnalyzer/Checkers/StdLibraryFunctionsChecker.cpp
index 356d63e3e8b80f..ab2a2cf95c9b36 100644
--- a/clang/lib/StaticAnalyzer/Checkers/StdLibraryFunctionsChecker.cpp
+++ b/clang/lib/StaticAnalyzer/Checkers/StdLibraryFunctionsChecker.cpp
@@ -3532,10 +3532,20 @@ void StdLibraryFunctionsChecker::initFunctionSummaries(
         Signature(ArgTypes{ConstTime_tPtrTy}, RetType{StructTmPtrTy}),
         Summary(NoEvalCall).ArgConstraint(NotNull(ArgNo(0))));
 
-    // struct tm *localtime_r(const time_t *restrict timer,
-    //                        struct tm *restrict result);
+    // struct tm *localtime_r(const time_t *timer,
+    //                        struct tm *result);
     addToFunctionSummaryMap(
         "localtime_r",
+        Signature(ArgTypes{ConstTime_tPtrTy, StructTmPtrTy},
+                  RetType{StructTmPtrTy}),
+        Summary(NoEvalCall)
+            .ArgConstraint(NotNull(ArgNo(0)))
+            .ArgConstraint(NotNull(ArgNo(1))));
+
+    // struct tm *localtime_s(const time_t *restrict timer,
+    //                        struct tm *restrict result);
+    addToFunctionSummaryMap(
+        "localtime_s",
         Signature(ArgTypes{ConstTime_tPtrRestrictTy, StructTmPtrRestrictTy},
                   RetType{StructTmPtrTy}),
         Summary(NoEvalCall)
@@ -3564,6 +3574,17 @@ void StdLibraryFunctionsChecker::initFunctionSummaries(
                 /*Buffer=*/ArgNo(1),
                 /*MinBufSize=*/BVF.getValue(26, IntTy))));
 
+    // char *ctime_r(char *buf, rsize_t buf_size, const time_t *timep);
+    addToFunctionSummaryMap(
+        "ctime_s",
+        Signature(ArgTypes{CharPtrTy, BufferSize(ArgNo(1), BVF.getValue(26, IntTy)), ConstTime_tPtrTy}, RetType{CharPtrTy}),
+        Summary(NoEvalCall)
+            .ArgConstraint(NotNull(ArgNo(0)))
+            .ArgConstraint(NotNull(ArgNo(1)))
+            .ArgConstraint(BufferSize(
+                /*Buffer=*/ArgNo(1),
+                /*MinBufSize=*/BVF.getValue(26, IntTy))));
+
     // struct tm *gmtime_r(const time_t *restrict timer,
     //                     struct tm *restrict result);
     addToFunctionSummaryMap(
diff --git a/clang/lib/Tooling/Inclusions/Stdlib/StdSymbolMap.inc b/clang/lib/Tooling/Inclusions/Stdlib/StdSymbolMap.inc
index c1927180d33976..65e3573282712b 100644
--- a/clang/lib/Tooling/Inclusions/Stdlib/StdSymbolMap.inc
+++ b/clang/lib/Tooling/Inclusions/Stdlib/StdSymbolMap.inc
@@ -2032,8 +2032,8 @@ SYMBOL(locale, std::, <locale>)
 SYMBOL(localeconv, std::, <clocale>)
 SYMBOL(localeconv, None, <clocale>)
 SYMBOL(localeconv, None, <locale.h>)
-SYMBOL(localtime, std::, <ctime>)
-SYMBOL(localtime, None, <ctime>)
+SYMBOL(localtime, std::, <localtime>)
+SYMBOL(localtime, None, <localtime>)
 SYMBOL(localtime, None, <time.h>)
 SYMBOL(lock, std::, <mutex>)
 SYMBOL(lock_guard, std::, <mutex>)
diff --git a/clang/test/Analysis/cert/env34-c.c b/clang/test/Analysis/cert/env34-c.c
index 0f1dd8707f98f4..3e764543b7ed0b 100644
--- a/clang/test/Analysis/cert/env34-c.c
+++ b/clang/test/Analysis/cert/env34-c.c
@@ -329,7 +329,7 @@ void ctime_test(void) {
   // expected-note at -2{{dereferencing an invalid pointer}}
 }
 
-void time_test(void) {
+void localtime_test(void) {
   const time_t *t;
   const time_t *tt;
 
diff --git a/compiler-rt/lib/dfsan/libc_ubuntu1404_abilist.txt b/compiler-rt/lib/dfsan/libc_ubuntu1404_abilist.txt
index 9ffa56a238185f..d0d6e74743d32f 100644
--- a/compiler-rt/lib/dfsan/libc_ubuntu1404_abilist.txt
+++ b/compiler-rt/lib/dfsan/libc_ubuntu1404_abilist.txt
@@ -1547,6 +1547,7 @@ fun:ctanl=uninstrumented
 fun:ctermid=uninstrumented
 fun:ctime=uninstrumented
 fun:ctime_r=uninstrumented
+fun:ctime_s=uninstrumented
 fun:cuserid=uninstrumented
 fun:daemon=uninstrumented
 fun:dcgettext=uninstrumented
@@ -2205,6 +2206,7 @@ fun:llseek=uninstrumented
 fun:localeconv=uninstrumented
 fun:localtime=uninstrumented
 fun:localtime_r=uninstrumented
+fun:localtime_s=uninstrumented
 fun:lockf=uninstrumented
 fun:lockf64=uninstrumented
 fun:log=uninstrumented
diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_common_interceptors.inc b/compiler-rt/lib/sanitizer_common/sanitizer_common_interceptors.inc
index 24a8a2d4dc55b4..bd410ceb1b41b5 100644
--- a/compiler-rt/lib/sanitizer_common/sanitizer_common_interceptors.inc
+++ b/compiler-rt/lib/sanitizer_common/sanitizer_common_interceptors.inc
@@ -1375,6 +1375,16 @@ INTERCEPTOR(__sanitizer_tm *, localtime_r, unsigned long *timep, void *result) {
   }
   return res;
 }
+INTERCEPTOR(__sanitizer_tm *, localtime_s, unsigned long *timep, void *result) {
+  void *ctx;
+  COMMON_INTERCEPTOR_ENTER(ctx, localtime_r, timep, result);
+  __sanitizer_tm *res = REAL(localtime_r)(timep, result);
+  if (res) {
+    COMMON_INTERCEPTOR_READ_RANGE(ctx, timep, sizeof(*timep));
+    unpoison_tm(ctx, res);
+  }
+  return res;
+}
 INTERCEPTOR(__sanitizer_tm *, gmtime, unsigned long *timep) {
   void *ctx;
   COMMON_INTERCEPTOR_ENTER(ctx, gmtime, timep);
@@ -1421,6 +1431,19 @@ INTERCEPTOR(char *, ctime_r, unsigned long *timep, char *result) {
   }
   return res;
 }
+INTERCEPTOR(char *, ctime_s, char* result, size_t result_size, unsigned long *timep) {
+  void *ctx;
+  COMMON_INTERCEPTOR_ENTER(ctx, ctime_s, result, result_size, timep);
+  // FIXME: under ASan the call below may write to freed memory and corrupt
+  // its metadata. See
+  // https://github.com/google/sanitizers/issues/321.
+  char *res = REAL(ctime_r)(result, result_size, timep);
+  if (res) {
+    COMMON_INTERCEPTOR_READ_RANGE(ctx, timep, sizeof(*timep));
+    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, internal_strlen(res) + 1);
+  }
+  return res;
+}
 INTERCEPTOR(char *, asctime, __sanitizer_tm *tm) {
   void *ctx;
   COMMON_INTERCEPTOR_ENTER(ctx, asctime, tm);

>From bfa132b7210f278420fbb6bfd46573e3992792f3 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: Thu, 26 Dec 2024 08:27:03 +0500
Subject: [PATCH 36/47] format code with clang-format

---
 .../Checkers/StdLibraryFunctionsChecker.cpp    | 18 ++++++++++--------
 .../sanitizer_common_interceptors.inc          |  3 ++-
 2 files changed, 12 insertions(+), 9 deletions(-)

diff --git a/clang/lib/StaticAnalyzer/Checkers/StdLibraryFunctionsChecker.cpp b/clang/lib/StaticAnalyzer/Checkers/StdLibraryFunctionsChecker.cpp
index ab2a2cf95c9b36..064e6ce2ac4164 100644
--- a/clang/lib/StaticAnalyzer/Checkers/StdLibraryFunctionsChecker.cpp
+++ b/clang/lib/StaticAnalyzer/Checkers/StdLibraryFunctionsChecker.cpp
@@ -3534,13 +3534,12 @@ void StdLibraryFunctionsChecker::initFunctionSummaries(
 
     // struct tm *localtime_r(const time_t *timer,
     //                        struct tm *result);
-    addToFunctionSummaryMap(
-        "localtime_r",
-        Signature(ArgTypes{ConstTime_tPtrTy, StructTmPtrTy},
-                  RetType{StructTmPtrTy}),
-        Summary(NoEvalCall)
-            .ArgConstraint(NotNull(ArgNo(0)))
-            .ArgConstraint(NotNull(ArgNo(1))));
+    addToFunctionSummaryMap("localtime_r",
+                            Signature(ArgTypes{ConstTime_tPtrTy, StructTmPtrTy},
+                                      RetType{StructTmPtrTy}),
+                            Summary(NoEvalCall)
+                                .ArgConstraint(NotNull(ArgNo(0)))
+                                .ArgConstraint(NotNull(ArgNo(1))));
 
     // struct tm *localtime_s(const time_t *restrict timer,
     //                        struct tm *restrict result);
@@ -3577,7 +3576,10 @@ void StdLibraryFunctionsChecker::initFunctionSummaries(
     // char *ctime_r(char *buf, rsize_t buf_size, const time_t *timep);
     addToFunctionSummaryMap(
         "ctime_s",
-        Signature(ArgTypes{CharPtrTy, BufferSize(ArgNo(1), BVF.getValue(26, IntTy)), ConstTime_tPtrTy}, RetType{CharPtrTy}),
+        Signature(ArgTypes{CharPtrTy,
+                           BufferSize(ArgNo(1), BVF.getValue(26, IntTy)),
+                           ConstTime_tPtrTy},
+                  RetType{CharPtrTy}),
         Summary(NoEvalCall)
             .ArgConstraint(NotNull(ArgNo(0)))
             .ArgConstraint(NotNull(ArgNo(1)))
diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_common_interceptors.inc b/compiler-rt/lib/sanitizer_common/sanitizer_common_interceptors.inc
index bd410ceb1b41b5..e0c334aa3fee41 100644
--- a/compiler-rt/lib/sanitizer_common/sanitizer_common_interceptors.inc
+++ b/compiler-rt/lib/sanitizer_common/sanitizer_common_interceptors.inc
@@ -1431,7 +1431,8 @@ INTERCEPTOR(char *, ctime_r, unsigned long *timep, char *result) {
   }
   return res;
 }
-INTERCEPTOR(char *, ctime_s, char* result, size_t result_size, unsigned long *timep) {
+INTERCEPTOR(char *, ctime_s, char *result, size_t result_size,
+            unsigned long *timep) {
   void *ctx;
   COMMON_INTERCEPTOR_ENTER(ctx, ctime_s, result, result_size, timep);
   // FIXME: under ASan the call below may write to freed memory and corrupt

>From dc31b20cd0327d42483a2116504c3250ec59242a 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: Thu, 26 Dec 2024 09:24:55 +0500
Subject: [PATCH 37/47] fix: document name

---
 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 c2425954640da5..8a1b74d9014071 100644
--- a/clang-tools-extra/docs/ReleaseNotes.rst
+++ b/clang-tools-extra/docs/ReleaseNotes.rst
@@ -191,7 +191,7 @@ Changes in existing checks
 
 - Added `ctime` and `localtime` to clang-tidy.
 
-- New unsafe functions checks :doc:`bugprone-unsafe-functions-check`
+- New unsafe functions checks :doc:`bugprone-unsafe-functions`
   <clang-tidy/bugprone/UnsafeFunctionsCheck.cpp> were added to clang-tidy.
 
 - Improved :doc:`bugprone-unsafe-functions

>From 679a424ada54ef67a61b2be9e62c639cc62ba968 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: Thu, 26 Dec 2024 09:38:43 +0500
Subject: [PATCH 38/47] fix: path for unsafe-functions

---
 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 8a1b74d9014071..1fb07daf874a05 100644
--- a/clang-tools-extra/docs/ReleaseNotes.rst
+++ b/clang-tools-extra/docs/ReleaseNotes.rst
@@ -195,7 +195,7 @@ Changes in existing checks
   <clang-tidy/bugprone/UnsafeFunctionsCheck.cpp> were added to clang-tidy.
 
 - Improved :doc:`bugprone-unsafe-functions
-  <clang-tidy/checks/bugprone/unsafe-functions>`, added `ctime` and `localtime`
+  <clang-tidy/checks/unsafe-functions>`, added `ctime` and `localtime`
   to unsafe functions check in clang-tidy.
 
 - Improved :doc:`bugprone-casting-through-void

>From fba6df0c393de95162c80b95eba23b346f374723 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: Thu, 26 Dec 2024 09:43:34 +0500
Subject: [PATCH 39/47] fix path

---
 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 1fb07daf874a05..8a1b74d9014071 100644
--- a/clang-tools-extra/docs/ReleaseNotes.rst
+++ b/clang-tools-extra/docs/ReleaseNotes.rst
@@ -195,7 +195,7 @@ Changes in existing checks
   <clang-tidy/bugprone/UnsafeFunctionsCheck.cpp> were added to clang-tidy.
 
 - Improved :doc:`bugprone-unsafe-functions
-  <clang-tidy/checks/unsafe-functions>`, added `ctime` and `localtime`
+  <clang-tidy/checks/bugprone/unsafe-functions>`, added `ctime` and `localtime`
   to unsafe functions check in clang-tidy.
 
 - Improved :doc:`bugprone-casting-through-void

>From dd51b45c451376e614dfb143ec3b5e9116b5f771 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: Thu, 26 Dec 2024 09:49:43 +0500
Subject: [PATCH 40/47] fix: release notes for clang-tidy

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

diff --git a/clang-tools-extra/docs/ReleaseNotes.rst b/clang-tools-extra/docs/ReleaseNotes.rst
index 8a1b74d9014071..ae2f4355600a7f 100644
--- a/clang-tools-extra/docs/ReleaseNotes.rst
+++ b/clang-tools-extra/docs/ReleaseNotes.rst
@@ -189,10 +189,8 @@ Changes in existing checks
   <clang-tidy/checks/bugprone/branch-clone>` check to improve detection of
   branch clones by now detecting duplicate inner and outer if statements.
 
-- Added `ctime` and `localtime` to clang-tidy.
-
-- New unsafe functions checks :doc:`bugprone-unsafe-functions`
-  <clang-tidy/bugprone/UnsafeFunctionsCheck.cpp> were added to clang-tidy.
+- New unsafe functions checks :doc:`bugprone-unsafe-functions
+  <clang-tidy/bugprone/UnsafeFunctionsCheck.cpp>` were added to clang-tidy.
 
 - Improved :doc:`bugprone-unsafe-functions
   <clang-tidy/checks/bugprone/unsafe-functions>`, added `ctime` and `localtime`

>From 0cfc05aae26fe0305978aaed1b4e0fd41328b5f3 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: Thu, 26 Dec 2024 09:56:44 +0500
Subject: [PATCH 41/47] fix: path for unsafe functions in release notes

---
 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 ae2f4355600a7f..942c4bacb67c07 100644
--- a/clang-tools-extra/docs/ReleaseNotes.rst
+++ b/clang-tools-extra/docs/ReleaseNotes.rst
@@ -190,7 +190,7 @@ Changes in existing checks
   branch clones by now detecting duplicate inner and outer if statements.
 
 - New unsafe functions checks :doc:`bugprone-unsafe-functions
-  <clang-tidy/bugprone/UnsafeFunctionsCheck.cpp>` were added to clang-tidy.
+  <clang-tidy/bugprone/UnsafeFunctionsCheck>` were added to clang-tidy.
 
 - Improved :doc:`bugprone-unsafe-functions
   <clang-tidy/checks/bugprone/unsafe-functions>`, added `ctime` and `localtime`

>From 67851156d9bf0e5b84ad02d5eda4db6b6649d09b 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: Thu, 26 Dec 2024 10:02:35 +0500
Subject: [PATCH 42/47] fix path for unsafe functions in release notes

---
 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 942c4bacb67c07..9240511709cc3e 100644
--- a/clang-tools-extra/docs/ReleaseNotes.rst
+++ b/clang-tools-extra/docs/ReleaseNotes.rst
@@ -190,7 +190,7 @@ Changes in existing checks
   branch clones by now detecting duplicate inner and outer if statements.
 
 - New unsafe functions checks :doc:`bugprone-unsafe-functions
-  <clang-tidy/bugprone/UnsafeFunctionsCheck>` were added to clang-tidy.
+  <clang-tidy/checks/bugprone/unsafe-functions>` were added to clang-tidy.
 
 - Improved :doc:`bugprone-unsafe-functions
   <clang-tidy/checks/bugprone/unsafe-functions>`, added `ctime` and `localtime`

>From 81fe4bd6e21fcef4ecc2b05c5765841f5e05d17f 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: Thu, 26 Dec 2024 10:27:33 +0500
Subject: [PATCH 43/47] fix: static analyzer for ctime_s

---
 .../StaticAnalyzer/Checkers/StdLibraryFunctionsChecker.cpp    | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/clang/lib/StaticAnalyzer/Checkers/StdLibraryFunctionsChecker.cpp b/clang/lib/StaticAnalyzer/Checkers/StdLibraryFunctionsChecker.cpp
index 064e6ce2ac4164..e3ec37a1f996d5 100644
--- a/clang/lib/StaticAnalyzer/Checkers/StdLibraryFunctionsChecker.cpp
+++ b/clang/lib/StaticAnalyzer/Checkers/StdLibraryFunctionsChecker.cpp
@@ -3573,7 +3573,7 @@ void StdLibraryFunctionsChecker::initFunctionSummaries(
                 /*Buffer=*/ArgNo(1),
                 /*MinBufSize=*/BVF.getValue(26, IntTy))));
 
-    // char *ctime_r(char *buf, rsize_t buf_size, const time_t *timep);
+    // char *ctime_s(char *buf, rsize_t buf_size, const time_t *timep);
     addToFunctionSummaryMap(
         "ctime_s",
         Signature(ArgTypes{CharPtrTy,
@@ -3582,10 +3582,10 @@ void StdLibraryFunctionsChecker::initFunctionSummaries(
                   RetType{CharPtrTy}),
         Summary(NoEvalCall)
             .ArgConstraint(NotNull(ArgNo(0)))
-            .ArgConstraint(NotNull(ArgNo(1)))
             .ArgConstraint(BufferSize(
                 /*Buffer=*/ArgNo(1),
                 /*MinBufSize=*/BVF.getValue(26, IntTy))));
+            .ArgConstraint(NotNull(ArgNo(1)))
 
     // struct tm *gmtime_r(const time_t *restrict timer,
     //                     struct tm *restrict result);

>From cdb7a00cf5506b34a8c1ff7385e2c2e32217b24e 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: Thu, 26 Dec 2024 10:32:36 +0500
Subject: [PATCH 44/47] fix argument number

---
 .../lib/StaticAnalyzer/Checkers/StdLibraryFunctionsChecker.cpp  | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/clang/lib/StaticAnalyzer/Checkers/StdLibraryFunctionsChecker.cpp b/clang/lib/StaticAnalyzer/Checkers/StdLibraryFunctionsChecker.cpp
index e3ec37a1f996d5..037271cf83ee95 100644
--- a/clang/lib/StaticAnalyzer/Checkers/StdLibraryFunctionsChecker.cpp
+++ b/clang/lib/StaticAnalyzer/Checkers/StdLibraryFunctionsChecker.cpp
@@ -3585,7 +3585,7 @@ void StdLibraryFunctionsChecker::initFunctionSummaries(
             .ArgConstraint(BufferSize(
                 /*Buffer=*/ArgNo(1),
                 /*MinBufSize=*/BVF.getValue(26, IntTy))));
-            .ArgConstraint(NotNull(ArgNo(1)))
+            .ArgConstraint(NotNull(ArgNo(2)))
 
     // struct tm *gmtime_r(const time_t *restrict timer,
     //                     struct tm *restrict result);

>From d82bf8c04ced53714aa99ebc2294ea5e00ffc5f7 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: Thu, 26 Dec 2024 10:32:58 +0500
Subject: [PATCH 45/47] format code with clang-format

---
 .../Checkers/StdLibraryFunctionsChecker.cpp   | 22 +++++++++----------
 1 file changed, 11 insertions(+), 11 deletions(-)

diff --git a/clang/lib/StaticAnalyzer/Checkers/StdLibraryFunctionsChecker.cpp b/clang/lib/StaticAnalyzer/Checkers/StdLibraryFunctionsChecker.cpp
index 037271cf83ee95..610191fac4dc0e 100644
--- a/clang/lib/StaticAnalyzer/Checkers/StdLibraryFunctionsChecker.cpp
+++ b/clang/lib/StaticAnalyzer/Checkers/StdLibraryFunctionsChecker.cpp
@@ -3585,17 +3585,17 @@ void StdLibraryFunctionsChecker::initFunctionSummaries(
             .ArgConstraint(BufferSize(
                 /*Buffer=*/ArgNo(1),
                 /*MinBufSize=*/BVF.getValue(26, IntTy))));
-            .ArgConstraint(NotNull(ArgNo(2)))
-
-    // struct tm *gmtime_r(const time_t *restrict timer,
-    //                     struct tm *restrict result);
-    addToFunctionSummaryMap(
-        "gmtime_r",
-        Signature(ArgTypes{ConstTime_tPtrRestrictTy, StructTmPtrRestrictTy},
-                  RetType{StructTmPtrTy}),
-        Summary(NoEvalCall)
-            .ArgConstraint(NotNull(ArgNo(0)))
-            .ArgConstraint(NotNull(ArgNo(1))));
+    .ArgConstraint(NotNull(ArgNo(2)))
+
+        // struct tm *gmtime_r(const time_t *restrict timer,
+        //                     struct tm *restrict result);
+        addToFunctionSummaryMap(
+            "gmtime_r",
+            Signature(ArgTypes{ConstTime_tPtrRestrictTy, StructTmPtrRestrictTy},
+                      RetType{StructTmPtrTy}),
+            Summary(NoEvalCall)
+                .ArgConstraint(NotNull(ArgNo(0)))
+                .ArgConstraint(NotNull(ArgNo(1))));
 
     // struct tm * gmtime(const time_t *tp);
     addToFunctionSummaryMap(

>From 892cef461ad6f64645d5f4da6aecc0cc5b578a19 Mon Sep 17 00:00:00 2001
From: Zishan Mirza <zmirza at posteo.de>
Date: Sat, 4 Jan 2025 16:11:54 +0500
Subject: [PATCH 46/47] include header file for size_t

---
 .../lib/sanitizer_common/sanitizer_common_interceptors.inc       | 1 +
 1 file changed, 1 insertion(+)

diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_common_interceptors.inc b/compiler-rt/lib/sanitizer_common/sanitizer_common_interceptors.inc
index e0c334aa3fee41..5a5982beeffbe0 100644
--- a/compiler-rt/lib/sanitizer_common/sanitizer_common_interceptors.inc
+++ b/compiler-rt/lib/sanitizer_common/sanitizer_common_interceptors.inc
@@ -34,6 +34,7 @@
 //===----------------------------------------------------------------------===//
 
 #include <stdarg.h>
+#include <stddef.h>
 
 #include "interception/interception.h"
 #include "sanitizer_addrhashmap.h"

>From 12ce09dfb550bdf18f7b61a786565e013e0200f6 Mon Sep 17 00:00:00 2001
From: Zishan Mirza <zmirza at posteo.de>
Date: Sat, 4 Jan 2025 16:27:37 +0500
Subject: [PATCH 47/47] fix clang static analyzer and functions checker

---
 .../StaticAnalyzer/Checkers/StdLibraryFunctionsChecker.cpp    | 4 ++--
 .../lib/sanitizer_common/sanitizer_common_interceptors.inc    | 2 +-
 2 files changed, 3 insertions(+), 3 deletions(-)

diff --git a/clang/lib/StaticAnalyzer/Checkers/StdLibraryFunctionsChecker.cpp b/clang/lib/StaticAnalyzer/Checkers/StdLibraryFunctionsChecker.cpp
index 610191fac4dc0e..750f66c3a8b8a3 100644
--- a/clang/lib/StaticAnalyzer/Checkers/StdLibraryFunctionsChecker.cpp
+++ b/clang/lib/StaticAnalyzer/Checkers/StdLibraryFunctionsChecker.cpp
@@ -3577,13 +3577,13 @@ void StdLibraryFunctionsChecker::initFunctionSummaries(
     addToFunctionSummaryMap(
         "ctime_s",
         Signature(ArgTypes{CharPtrTy,
-                           BufferSize(ArgNo(1), BVF.getValue(26, IntTy)),
+                           BufferSize(ArgNo(0), BVF.getValue(26, IntTy)),
                            ConstTime_tPtrTy},
                   RetType{CharPtrTy}),
         Summary(NoEvalCall)
             .ArgConstraint(NotNull(ArgNo(0)))
             .ArgConstraint(BufferSize(
-                /*Buffer=*/ArgNo(1),
+                /*Buffer=*/ArgNo(0),
                 /*MinBufSize=*/BVF.getValue(26, IntTy))));
     .ArgConstraint(NotNull(ArgNo(2)))
 
diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_common_interceptors.inc b/compiler-rt/lib/sanitizer_common/sanitizer_common_interceptors.inc
index 5a5982beeffbe0..c7cf307a126644 100644
--- a/compiler-rt/lib/sanitizer_common/sanitizer_common_interceptors.inc
+++ b/compiler-rt/lib/sanitizer_common/sanitizer_common_interceptors.inc
@@ -1439,7 +1439,7 @@ INTERCEPTOR(char *, ctime_s, char *result, size_t result_size,
   // FIXME: under ASan the call below may write to freed memory and corrupt
   // its metadata. See
   // https://github.com/google/sanitizers/issues/321.
-  char *res = REAL(ctime_r)(result, result_size, timep);
+  char *res = REAL(ctime_s)(result, result_size, timep);
   if (res) {
     COMMON_INTERCEPTOR_READ_RANGE(ctx, timep, sizeof(*timep));
     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, internal_strlen(res) + 1);



More information about the llvm-commits mailing list