[clang] [clang-cl] Add cl compiler build deterministic options for compatibility. (PR #194779)
Vladimir Vereschaka via cfe-commits
cfe-commits at lists.llvm.org
Tue Jun 16 19:22:45 PDT 2026
https://github.com/vvereschaka updated https://github.com/llvm/llvm-project/pull/194779
>From f12e9a46d194a36edd1dd0b6f62ec2a21cde7d8f Mon Sep 17 00:00:00 2001
From: Vladimir Vereschaka <vvereschaka at accesssoftek.com>
Date: Tue, 28 Apr 2026 21:21:47 -0700
Subject: [PATCH 01/14] [clang-cl] Add cl compiler build deterministic options
for compatibility.
Added the following options:
* /experimental:deterministic (emits clang -Wdate-time option)
Emit warnings on usage of non-deterministic macros __DATE__, __TIME__ and __TIMESTAMP__
* /d1nodatetime (emits clang -Wno-builtin-macro-redefined option)
Undefine the standard preprocessor macros __DATE__, __TIME__ and __TIMESTAMP__
---
clang/include/clang/Options/Options.td | 4 +++
clang/lib/Driver/ToolChains/Clang.cpp | 11 ++++++++
clang/test/Driver/cl-deterministic.c | 36 ++++++++++++++++++++++++++
3 files changed, 51 insertions(+)
create mode 100644 clang/test/Driver/cl-deterministic.c
diff --git a/clang/include/clang/Options/Options.td b/clang/include/clang/Options/Options.td
index 8f5ed945a40fe..899f5c42321a4 100644
--- a/clang/include/clang/Options/Options.td
+++ b/clang/include/clang/Options/Options.td
@@ -9334,6 +9334,10 @@ def : CLFlag<"Qgather-">, Alias<mno_gather>,
HelpText<"Disable generation of gather instructions in auto-vectorization(x86 only)">;
def : CLFlag<"Qscatter-">, Alias<mno_scatter>,
HelpText<"Disable generation of scatter instructions in auto-vectorization(x86 only)">;
+def _SLASH_experemental_deterministic : CLJoined<"experimental:deterministic">,
+ HelpText<"Emit warnings on usage of non-deterministic macros __DATE__, __TIME__ and __TIMESTAMP__">;
+def _SLASH_d1nodatetime : CLFlag<"d1nodatetime">,
+ HelpText<"Undefine the standard preprocessor macros __DATE__, __TIME__ and __TIMESTAMP__">;
// Non-aliases:
diff --git a/clang/lib/Driver/ToolChains/Clang.cpp b/clang/lib/Driver/ToolChains/Clang.cpp
index b25bddf5a94e8..36cae95148d7e 100644
--- a/clang/lib/Driver/ToolChains/Clang.cpp
+++ b/clang/lib/Driver/ToolChains/Clang.cpp
@@ -8896,6 +8896,17 @@ void Clang::AddClangCLArgs(const ArgList &Args, types::ID InputType,
CmdArgs.push_back(Args.MakeArgString(
Twine("-loader-replaceable-function=") + FuncOverride));
}
+
+ if (Args.hasFlag(options::OPT__SLASH_experemental_deterministic,
+ options::OPT__SLASH_experemental_deterministic, false)) {
+ CmdArgs.push_back("-Wdate-time");
+ }
+
+ if (Args.hasFlag(options::OPT__SLASH_d1nodatetime,
+ options::OPT__SLASH_d1nodatetime, false)) {
+ CmdArgs.push_back("-Wno-builtin-macro-redefined");
+ }
+
}
const char *Clang::getBaseInputName(const ArgList &Args,
diff --git a/clang/test/Driver/cl-deterministic.c b/clang/test/Driver/cl-deterministic.c
new file mode 100644
index 0000000000000..2c3df5f37d014
--- /dev/null
+++ b/clang/test/Driver/cl-deterministic.c
@@ -0,0 +1,36 @@
+// We have to run the compilation step to see the output, so we must be able to
+// target Windows.
+
+// REQUIRES: system-windows
+
+// RUN: %clang_cl -fno-integrated-cc1 -E /experimental:deterministic /d1nodatetime %s
+// RUN: %clang_cl -fno-integrated-cc1 -E /D IS_SYSHEADER=1 /experimental:deterministic /d1nodatetime %s
+
+// RUN: %clang_cl -E /experimental:deterministic /d1nodatetime %s
+// RUN: %clang_cl -E /D IS_SYSHEADER=1 /experimental:deterministic /d1nodatetime %s
+
+// not %clang_cc1 -Werror=date-time -Wno-builtin-macro-redefined %s -DIS_SYSHEADER -E 2>&1 | grep 'error: expansion' | count 3
+
+// RUN: %clang_cl -E -### /experimental:deterministic %s 2>&1 | FileCheck %s --check-prefix=WDATETIME
+// WDATETIME: -Wdate-time
+// RUN: %clang_cl -E -### /d1nodatetime %s 2>&1 | FileCheck %s --check-prefix=MACROREDEF
+// MACROREDEF: -Wno-builtin-macro-redefined
+
+#ifdef IS_HEADER
+
+#ifdef IS_SYSHEADER
+#pragma clang system_header
+#endif
+
+__TIME__ // expected-warning {{expansion of date or time macro is not reproducible}}
+__DATE__ // expected-warning {{expansion of date or time macro is not reproducible}}
+__TIMESTAMP__ // expected-warning {{expansion of date or time macro is not reproducible}}
+
+#define __TIME__
+__TIME__
+
+#else
+
+#define IS_HEADER
+#include __FILE__
+#endif
\ No newline at end of file
>From a493089b1f052e21a3c572fd9d6c2e6cf7b0ad60 Mon Sep 17 00:00:00 2001
From: Vladimir Vereschaka <vvereschaka at accesssoftek.com>
Date: Tue, 28 Apr 2026 22:18:36 -0700
Subject: [PATCH 02/14] Clean up empty lines
---
clang/lib/Driver/ToolChains/Clang.cpp | 1 -
1 file changed, 1 deletion(-)
diff --git a/clang/lib/Driver/ToolChains/Clang.cpp b/clang/lib/Driver/ToolChains/Clang.cpp
index 36cae95148d7e..c730d9586a7ec 100644
--- a/clang/lib/Driver/ToolChains/Clang.cpp
+++ b/clang/lib/Driver/ToolChains/Clang.cpp
@@ -8906,7 +8906,6 @@ void Clang::AddClangCLArgs(const ArgList &Args, types::ID InputType,
options::OPT__SLASH_d1nodatetime, false)) {
CmdArgs.push_back("-Wno-builtin-macro-redefined");
}
-
}
const char *Clang::getBaseInputName(const ArgList &Args,
>From d3b62eb2fea5e2c6deb550468f40ce14985f6ded Mon Sep 17 00:00:00 2001
From: Vladimir Vereschaka <vvereschaka at accesssoftek.com>
Date: Thu, 14 May 2026 22:58:13 -0700
Subject: [PATCH 03/14] Updated CL's deterministic options:
/experemental:determenistic, /d1nodatetime and /Brepro.
---
clang/include/clang/Options/Options.td | 2 +
clang/lib/Driver/ToolChains/Clang.cpp | 60 ++++++++++++++++++++++----
2 files changed, 54 insertions(+), 8 deletions(-)
diff --git a/clang/include/clang/Options/Options.td b/clang/include/clang/Options/Options.td
index 899f5c42321a4..5d3642a442e2d 100644
--- a/clang/include/clang/Options/Options.td
+++ b/clang/include/clang/Options/Options.td
@@ -9338,6 +9338,8 @@ def _SLASH_experemental_deterministic : CLJoined<"experimental:deterministic">,
HelpText<"Emit warnings on usage of non-deterministic macros __DATE__, __TIME__ and __TIMESTAMP__">;
def _SLASH_d1nodatetime : CLFlag<"d1nodatetime">,
HelpText<"Undefine the standard preprocessor macros __DATE__, __TIME__ and __TIMESTAMP__">;
+def _SLASH_d1nodatetime_ : CLFlag<"d1nodatetime-">,
+ HelpText<"Disable undefinition of the standard preprocessor macros __DATE__, __TIME__ and __TIMESTAMP__">;
// Non-aliases:
diff --git a/clang/lib/Driver/ToolChains/Clang.cpp b/clang/lib/Driver/ToolChains/Clang.cpp
index c730d9586a7ec..fd859d2c21470 100644
--- a/clang/lib/Driver/ToolChains/Clang.cpp
+++ b/clang/lib/Driver/ToolChains/Clang.cpp
@@ -8897,15 +8897,59 @@ void Clang::AddClangCLArgs(const ArgList &Args, types::ID InputType,
Twine("-loader-replaceable-function=") + FuncOverride));
}
- if (Args.hasFlag(options::OPT__SLASH_experemental_deterministic,
- options::OPT__SLASH_experemental_deterministic, false)) {
- CmdArgs.push_back("-Wdate-time");
- }
+ auto findMacro = [&](const std::string &Macro, bool claim = false) {
+ for (const auto *A : Args.filtered(options::OPT_D, options::OPT_U)) {
+ const std::string v(A->getValue());
+ if (v == Macro || v.find(Macro + '=') != std::string::npos)
+ if (claim)
+ A->claim();
+ return true;
+ }
+ return false;
+ };
- if (Args.hasFlag(options::OPT__SLASH_d1nodatetime,
- options::OPT__SLASH_d1nodatetime, false)) {
- CmdArgs.push_back("-Wno-builtin-macro-redefined");
- }
+ if (Args.hasArg(options::OPT__SLASH_experemental_deterministic)) {
+ CmdArgs.push_back("-Wdate-time");
+
+ if (Args.hasArg(options::OPT_mincremental_linker_compatible)) {
+ D.Diag(diag::err_drv_argument_not_allowed_with) << "/experemental:determenistic"
+ << "/Brepro-";
+ }
+ // CL's sets COFF's OBJ timestamp to a hash of the source file path to get deterministic
+ // result, but we force this timestamp to 0, which also produces determinitic result.
+ CmdArgs.push_back("-mno-incremental-linker-compatible");
+ }
+
+ if (Args.hasFlag(options::OPT__SLASH_d1nodatetime,
+ options::OPT__SLASH_d1nodatetime_, false)) {
+ // Allow user definitions for these macros from the command line.
+ CmdArgs.push_back("-Wno-builtin-macro-redefined");
+ if (!findMacro("__DATE__"))
+ CmdArgs.push_back("-U__DATE__");
+ if (!findMacro("__TIME__"))
+ CmdArgs.push_back("-U__TIME__");
+ if (!findMacro("__TIMESTAMP__"))
+ CmdArgs.push_back("-U__TIMESTAMP__");
+ }
+
+ // /Brepro is an alias for -mincremental-linker-compatible option.
+ if (!Args.hasFlag(options::OPT_mincremental_linker_compatible,
+ options::OPT_mno_incremental_linker_compatible,
+ getToolChain().getTriple().isDefaultIncrementalLinkerCompatibleByDefault())) {
+ // Redefine the date/time macros only if /d1nodatetime wasn't specified.
+ // This options does not allow the user redifinitions for these macros.
+ if (!Args.hasFlag(options::OPT__SLASH_d1nodatetime,
+ options::OPT__SLASH_d1nodatetime_, false)) {
+ findMacro("__DATE__", true);
+ findMacro("__TIME__", true);
+ findMacro("__TIMESTAMP__", true);
+
+ CmdArgs.push_back("-Wno-builtin-macro-redefined");
+ CmdArgs.push_back("-D__DATE__=\"1\"");
+ CmdArgs.push_back("-D__TIME__=\"1\"");
+ CmdArgs.push_back("-D__TIMESTAMP__=\"1\"");
+ }
+ }
}
const char *Clang::getBaseInputName(const ArgList &Args,
>From 94bc214d38b3d60205209100da58a6794d258ac9 Mon Sep 17 00:00:00 2001
From: Vladimir Vereschaka <vvereschaka at accesssoftek.com>
Date: Thu, 14 May 2026 23:24:50 -0700
Subject: [PATCH 04/14] Fixed typos
---
clang/include/clang/Options/Options.td | 2 +-
clang/lib/Driver/ToolChains/Clang.cpp | 6 +++---
2 files changed, 4 insertions(+), 4 deletions(-)
diff --git a/clang/include/clang/Options/Options.td b/clang/include/clang/Options/Options.td
index 5d3642a442e2d..912b3bc610f6a 100644
--- a/clang/include/clang/Options/Options.td
+++ b/clang/include/clang/Options/Options.td
@@ -9334,7 +9334,7 @@ def : CLFlag<"Qgather-">, Alias<mno_gather>,
HelpText<"Disable generation of gather instructions in auto-vectorization(x86 only)">;
def : CLFlag<"Qscatter-">, Alias<mno_scatter>,
HelpText<"Disable generation of scatter instructions in auto-vectorization(x86 only)">;
-def _SLASH_experemental_deterministic : CLJoined<"experimental:deterministic">,
+def _SLASH_experimental_deterministic : CLJoined<"experimental:deterministic">,
HelpText<"Emit warnings on usage of non-deterministic macros __DATE__, __TIME__ and __TIMESTAMP__">;
def _SLASH_d1nodatetime : CLFlag<"d1nodatetime">,
HelpText<"Undefine the standard preprocessor macros __DATE__, __TIME__ and __TIMESTAMP__">;
diff --git a/clang/lib/Driver/ToolChains/Clang.cpp b/clang/lib/Driver/ToolChains/Clang.cpp
index fd859d2c21470..04b8cbebd8993 100644
--- a/clang/lib/Driver/ToolChains/Clang.cpp
+++ b/clang/lib/Driver/ToolChains/Clang.cpp
@@ -8908,15 +8908,15 @@ void Clang::AddClangCLArgs(const ArgList &Args, types::ID InputType,
return false;
};
- if (Args.hasArg(options::OPT__SLASH_experemental_deterministic)) {
+ if (Args.hasArg(options::OPT__SLASH_experimental_deterministic)) {
CmdArgs.push_back("-Wdate-time");
if (Args.hasArg(options::OPT_mincremental_linker_compatible)) {
- D.Diag(diag::err_drv_argument_not_allowed_with) << "/experemental:determenistic"
+ D.Diag(diag::err_drv_argument_not_allowed_with) << "/experimental:deterministic"
<< "/Brepro-";
}
// CL's sets COFF's OBJ timestamp to a hash of the source file path to get deterministic
- // result, but we force this timestamp to 0, which also produces determinitic result.
+ // result, but we force this timestamp to 0, which also produces deterministic result.
CmdArgs.push_back("-mno-incremental-linker-compatible");
}
>From 0c873722684c8ee5c22cde442bcfaffd3598e24f Mon Sep 17 00:00:00 2001
From: Vladimir Vereschaka <vvereschaka at accesssoftek.com>
Date: Tue, 19 May 2026 12:32:23 -0700
Subject: [PATCH 05/14] Added `-init-datetime-macros=` cc1 option. Updated
ReleaseNotes.rst.
Updated other options accordingly.
---
clang/docs/ReleaseNotes.rst | 15 +++
clang/include/clang/Lex/PreprocessorOptions.h | 16 +++
clang/include/clang/Options/Options.td | 5 +
clang/lib/Driver/ToolChains/Clang.cpp | 39 ++-----
clang/lib/Lex/PPMacroExpansion.cpp | 102 ++++++++++++------
clang/test/Driver/cl-deterministic.c | 5 +-
.../test/Preprocessor/init-datetime-macros.c | 60 +++++++++++
7 files changed, 178 insertions(+), 64 deletions(-)
create mode 100644 clang/test/Preprocessor/init-datetime-macros.c
diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index 5e7a0c76d4594..d599aaa9626d0 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -393,6 +393,17 @@ New Compiler Flags
a hostname when generates the hashes. Known issues -- does not remap the
source file pathes within PCH/PCM files.
+- New ``-cl`` option ``/experimental:deterministic`` added to match CL's option.
+ This enables warning emission on usage of non-deterministic macros __DATE__,
+ __TIME__ and __TIMESTAMP__ and provides reproducable COFF's timestamp for
+ the output object files.
+
+- New ``-cl`` option ``/d1nodatetime`` added to match CL's option. This option
+ undefines the standard macros __DATE__, __TIME__ and __TIMESTAMP__ to allow
+ reproducable builds. These macros can be redefined from the command line if
+ necessary. ``/d1nodatetime-`` can be used to turn this feature off if
+ necessary to override the common build settings.
+
Deprecated Compiler Flags
-------------------------
@@ -407,6 +418,10 @@ Modified Compiler Flags
normalized in favor of the target system (same as the preprocessor does
for the file macros) and allows the reproducable IDs on any build system.
+- The ``-cl`` ``/Brepro`` option was modified to match the original CL's option
+ and now defines the standard macros __DATE__, __TIME__ and __TIMESTAMP__ to
+ "1". The previous functionality remains unchanged.
+
Removed Compiler Flags
----------------------
diff --git a/clang/include/clang/Lex/PreprocessorOptions.h b/clang/include/clang/Lex/PreprocessorOptions.h
index db80eecce4908..4d1a30712836f 100644
--- a/clang/include/clang/Lex/PreprocessorOptions.h
+++ b/clang/include/clang/Lex/PreprocessorOptions.h
@@ -43,6 +43,18 @@ enum ObjCXXARCStandardLibraryKind {
ARCXX_libstdcxx
};
+/// How to initialize the date/time macros.
+enum DateTimeInitKind {
+ /// Set to the current date and time.
+ Default = 0,
+
+ /// Set to literal string "1".
+ LiteralOne = 1,
+
+ /// Keep undefined.
+ Undefined = 2
+};
+
/// Whether to disable the normal validation performed on precompiled
/// headers and module files when they are loaded.
enum class DisableValidationForModuleKind {
@@ -209,6 +221,10 @@ class PreprocessorOptions {
/// -cc1 flag for testing purposes.
uint32_t InitialCounterValue = 0;
+ /// Specify initialization kind for __DATE__, __TIME__ and __TIMESTAMP__
+ /// macros.
+ DateTimeInitKind InitDateTimeMacros = DateTimeInitKind::Default;
+
public:
PreprocessorOptions() : PrecompiledPreambleBytes(0, false) {}
diff --git a/clang/include/clang/Options/Options.td b/clang/include/clang/Options/Options.td
index 912b3bc610f6a..e3bddc0d51ac0 100644
--- a/clang/include/clang/Options/Options.td
+++ b/clang/include/clang/Options/Options.td
@@ -8896,6 +8896,11 @@ def fno_modules_check_relocated
Group<f_Group>,
HelpText<"Skip checks for relocated modules when loading PCM files">,
MarshallingInfoNegativeFlag<PreprocessorOpts<"ModulesCheckRelocated">>;
+def init_datetime_macros_EQ : Joined<["-"], "init-datetime-macros=">,
+ HelpText<"Change __DATE__, __TIME__, and __TIMESTAMP__ macros initialization and expansion">,
+ Values<"default,literalone,undefined">,
+ NormalizedValues<["Default", "LiteralOne", "Undefined"]>,
+ MarshallingInfoEnum<PreprocessorOpts<"InitDateTimeMacros">, "Default">;
} // let Visibility = [CC1Option]
diff --git a/clang/lib/Driver/ToolChains/Clang.cpp b/clang/lib/Driver/ToolChains/Clang.cpp
index 04b8cbebd8993..4ffb0acca56fb 100644
--- a/clang/lib/Driver/ToolChains/Clang.cpp
+++ b/clang/lib/Driver/ToolChains/Clang.cpp
@@ -8897,39 +8897,23 @@ void Clang::AddClangCLArgs(const ArgList &Args, types::ID InputType,
Twine("-loader-replaceable-function=") + FuncOverride));
}
- auto findMacro = [&](const std::string &Macro, bool claim = false) {
- for (const auto *A : Args.filtered(options::OPT_D, options::OPT_U)) {
- const std::string v(A->getValue());
- if (v == Macro || v.find(Macro + '=') != std::string::npos)
- if (claim)
- A->claim();
- return true;
- }
- return false;
- };
-
if (Args.hasArg(options::OPT__SLASH_experimental_deterministic)) {
CmdArgs.push_back("-Wdate-time");
if (Args.hasArg(options::OPT_mincremental_linker_compatible)) {
- D.Diag(diag::err_drv_argument_not_allowed_with) << "/experimental:deterministic"
- << "/Brepro-";
+ D.Diag(diag::err_drv_argument_not_allowed_with)
+ << "/experimental:deterministic"
+ << "/Brepro-";
}
- // CL's sets COFF's OBJ timestamp to a hash of the source file path to get deterministic
- // result, but we force this timestamp to 0, which also produces deterministic result.
+ // CL's sets COFF's OBJ timestamp to a hash of the source file path to get
+ // deterministic result, but we force this timestamp to 0, which also
+ // produces deterministic result.
CmdArgs.push_back("-mno-incremental-linker-compatible");
}
if (Args.hasFlag(options::OPT__SLASH_d1nodatetime,
options::OPT__SLASH_d1nodatetime_, false)) {
- // Allow user definitions for these macros from the command line.
- CmdArgs.push_back("-Wno-builtin-macro-redefined");
- if (!findMacro("__DATE__"))
- CmdArgs.push_back("-U__DATE__");
- if (!findMacro("__TIME__"))
- CmdArgs.push_back("-U__TIME__");
- if (!findMacro("__TIMESTAMP__"))
- CmdArgs.push_back("-U__TIMESTAMP__");
+ CmdArgs.push_back("-init-datetime-macros=undefined");
}
// /Brepro is an alias for -mincremental-linker-compatible option.
@@ -8940,14 +8924,7 @@ void Clang::AddClangCLArgs(const ArgList &Args, types::ID InputType,
// This options does not allow the user redifinitions for these macros.
if (!Args.hasFlag(options::OPT__SLASH_d1nodatetime,
options::OPT__SLASH_d1nodatetime_, false)) {
- findMacro("__DATE__", true);
- findMacro("__TIME__", true);
- findMacro("__TIMESTAMP__", true);
-
- CmdArgs.push_back("-Wno-builtin-macro-redefined");
- CmdArgs.push_back("-D__DATE__=\"1\"");
- CmdArgs.push_back("-D__TIME__=\"1\"");
- CmdArgs.push_back("-D__TIMESTAMP__=\"1\"");
+ CmdArgs.push_back("-init-datetime-macros=literalone");
}
}
}
diff --git a/clang/lib/Lex/PPMacroExpansion.cpp b/clang/lib/Lex/PPMacroExpansion.cpp
index 5fd3512d2f45c..23a21f42b8e3a 100644
--- a/clang/lib/Lex/PPMacroExpansion.cpp
+++ b/clang/lib/Lex/PPMacroExpansion.cpp
@@ -324,8 +324,15 @@ void Preprocessor::dumpMacroInfo(const IdentifierInfo *II) {
void Preprocessor::RegisterBuiltinMacros() {
Ident__LINE__ = RegisterBuiltinMacro("__LINE__");
Ident__FILE__ = RegisterBuiltinMacro("__FILE__");
- Ident__DATE__ = RegisterBuiltinMacro("__DATE__");
- Ident__TIME__ = RegisterBuiltinMacro("__TIME__");
+ // Keep __DATE__, __TIME__ and __TIMESTAMP__ undefined if it was requested.
+ // Those macros still be able defined from the command line.
+ if (getPreprocessorOpts().InitDateTimeMacros != DateTimeInitKind::Undefined) {
+ Ident__DATE__ = RegisterBuiltinMacro("__DATE__");
+ Ident__TIME__ = RegisterBuiltinMacro("__TIME__");
+ } else {
+ Ident__DATE__ = nullptr;
+ Ident__TIME__ = nullptr;
+ }
Ident__COUNTER__ = RegisterBuiltinMacro("__COUNTER__");
Ident_Pragma = RegisterBuiltinMacro("_Pragma");
Ident__FLT_EVAL_METHOD__ = RegisterBuiltinMacro("__FLT_EVAL_METHOD__");
@@ -339,7 +346,10 @@ void Preprocessor::RegisterBuiltinMacros() {
// GCC Extensions.
Ident__BASE_FILE__ = RegisterBuiltinMacro("__BASE_FILE__");
Ident__INCLUDE_LEVEL__ = RegisterBuiltinMacro("__INCLUDE_LEVEL__");
- Ident__TIMESTAMP__ = RegisterBuiltinMacro("__TIMESTAMP__");
+ if (getPreprocessorOpts().InitDateTimeMacros != DateTimeInitKind::Undefined)
+ Ident__TIMESTAMP__ = RegisterBuiltinMacro("__TIMESTAMP__");
+ else
+ Ident__TIMESTAMP__ = nullptr;
// Microsoft Extensions.
if (getLangOpts().MicrosoftExt) {
@@ -1040,8 +1050,32 @@ void Preprocessor::removeCachedMacroExpandedTokensOfLastLexer() {
/// ComputeDATE_TIME - Compute the current time, enter it into the specified
/// scratch buffer, then return DATELoc/TIMELoc locations with the position of
/// the identifier tokens inserted.
-static void ComputeDATE_TIME(SourceLocation &DATELoc, SourceLocation &TIMELoc,
+static void ComputeDATE_TIME(SourceLocation &DATELoc, size_t &DATETokLen,
+ SourceLocation &TIMELoc, size_t &TIMETokLen,
Preprocessor &PP) {
+
+ if (PP.getPreprocessorOpts().InitDateTimeMacros ==
+ DateTimeInitKind::LiteralOne) {
+ if (!DATELoc.isValid()) {
+ Token TmpTok;
+ TmpTok.startToken();
+ PP.CreateString("\"1\"", TmpTok);
+ DATELoc = TmpTok.getLocation();
+ }
+ // Always set up and return a token length for both - DATE and TIME.
+ DATETokLen = strlen("\"1\"");
+
+ if (!TIMELoc.isValid()) {
+ Token TmpTok;
+ TmpTok.startToken();
+ PP.CreateString("\"1\"", TmpTok);
+ TIMELoc = TmpTok.getLocation();
+ }
+ TIMETokLen = strlen("\"1\"");
+
+ return;
+ }
+
time_t TT;
std::tm *TM;
if (PP.getPreprocessorOpts().SourceDateEpoch) {
@@ -1056,7 +1090,7 @@ static void ComputeDATE_TIME(SourceLocation &DATELoc, SourceLocation &TIMELoc,
"Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"
};
- {
+ if (!DATELoc.isValid()) {
SmallString<32> TmpBuffer;
llvm::raw_svector_ostream TmpStream(TmpBuffer);
if (TM)
@@ -1069,8 +1103,9 @@ static void ComputeDATE_TIME(SourceLocation &DATELoc, SourceLocation &TIMELoc,
PP.CreateString(TmpStream.str(), TmpTok);
DATELoc = TmpTok.getLocation();
}
+ DATETokLen = strlen("\"Mmm dd yyyy\"");
- {
+ if (!TIMELoc.isValid()) {
SmallString<32> TmpBuffer;
llvm::raw_svector_ostream TmpStream(TmpBuffer);
if (TM)
@@ -1083,6 +1118,7 @@ static void ComputeDATE_TIME(SourceLocation &DATELoc, SourceLocation &TIMELoc,
PP.CreateString(TmpStream.str(), TmpTok);
TIMELoc = TmpTok.getLocation();
}
+ TIMETokLen = strlen("\"hh:mm:ss\"");
}
/// HasFeature - Return true if we recognize and implement the feature
@@ -1659,20 +1695,22 @@ void Preprocessor::ExpandBuiltinMacro(Token &Tok) {
Tok.setKind(tok::string_literal);
} else if (II == Ident__DATE__) {
Diag(Tok.getLocation(), diag::warn_pp_date_time);
- if (!DATELoc.isValid())
- ComputeDATE_TIME(DATELoc, TIMELoc, *this);
+
+ size_t TIMETokLen = 0, DATETokLen = 0;
+ ComputeDATE_TIME(DATELoc, DATETokLen, TIMELoc, TIMETokLen, *this);
Tok.setKind(tok::string_literal);
- Tok.setLength(strlen("\"Mmm dd yyyy\""));
+ Tok.setLength(DATETokLen);
Tok.setLocation(SourceMgr.createExpansionLoc(DATELoc, Tok.getLocation(),
Tok.getLocation(),
Tok.getLength()));
return;
} else if (II == Ident__TIME__) {
Diag(Tok.getLocation(), diag::warn_pp_date_time);
- if (!TIMELoc.isValid())
- ComputeDATE_TIME(DATELoc, TIMELoc, *this);
+
+ size_t TIMETokLen = 0, DATETokLen = 0;
+ ComputeDATE_TIME(DATELoc, DATETokLen, TIMELoc, TIMETokLen, *this);
Tok.setKind(tok::string_literal);
- Tok.setLength(strlen("\"hh:mm:ss\""));
+ Tok.setLength(TIMETokLen);
Tok.setLocation(SourceMgr.createExpansionLoc(TIMELoc, Tok.getLocation(),
Tok.getLocation(),
Tok.getLength()));
@@ -1696,28 +1734,32 @@ void Preprocessor::ExpandBuiltinMacro(Token &Tok) {
Diag(Tok.getLocation(), diag::warn_pp_date_time);
// MSVC, ICC, GCC, VisualAge C++ extension. The generated string should be
// of the form "Ddd Mmm dd hh::mm::ss yyyy", which is returned by asctime.
- std::string Result;
+ std::string Result = "1"; // DateTimeInitKind::LiteralOne by default.
std::stringstream TmpStream;
- TmpStream.imbue(std::locale("C"));
- if (getPreprocessorOpts().SourceDateEpoch) {
- time_t TT = *getPreprocessorOpts().SourceDateEpoch;
- std::tm *TM = std::gmtime(&TT);
- TmpStream << std::put_time(TM, "%a %b %e %T %Y");
- } else {
- // Get the file that we are lexing out of. If we're currently lexing from
- // a macro, dig into the include stack.
- const FileEntry *CurFile = nullptr;
- if (PreprocessorLexer *TheLexer = getCurrentFileLexer())
- CurFile = SourceMgr.getFileEntryForID(TheLexer->getFileID());
- if (CurFile) {
- time_t TT = CurFile->getModificationTime();
- struct tm *TM = localtime(&TT);
+
+ // Requested regular __TIMESTAMP__ initialization.
+ if (getPreprocessorOpts().InitDateTimeMacros == DateTimeInitKind::Default) {
+ TmpStream.imbue(std::locale("C"));
+ if (getPreprocessorOpts().SourceDateEpoch) {
+ time_t TT = *getPreprocessorOpts().SourceDateEpoch;
+ std::tm *TM = std::gmtime(&TT);
TmpStream << std::put_time(TM, "%a %b %e %T %Y");
+ } else {
+ // Get the file that we are lexing out of. If we're currently lexing
+ // from a macro, dig into the include stack.
+ const FileEntry *CurFile = nullptr;
+ if (PreprocessorLexer *TheLexer = getCurrentFileLexer())
+ CurFile = SourceMgr.getFileEntryForID(TheLexer->getFileID());
+ if (CurFile) {
+ time_t TT = CurFile->getModificationTime();
+ struct tm *TM = localtime(&TT);
+ TmpStream << std::put_time(TM, "%a %b %e %T %Y");
+ }
}
+ Result = TmpStream.str();
+ if (Result.empty())
+ Result = "??? ??? ?? ??:??:?? ????";
}
- Result = TmpStream.str();
- if (Result.empty())
- Result = "??? ??? ?? ??:??:?? ????";
OS << '"' << Result << '"';
Tok.setKind(tok::string_literal);
} else if (II == Ident__FLT_EVAL_METHOD__) {
diff --git a/clang/test/Driver/cl-deterministic.c b/clang/test/Driver/cl-deterministic.c
index 2c3df5f37d014..50ef612594f3e 100644
--- a/clang/test/Driver/cl-deterministic.c
+++ b/clang/test/Driver/cl-deterministic.c
@@ -1,8 +1,6 @@
// We have to run the compilation step to see the output, so we must be able to
// target Windows.
-// REQUIRES: system-windows
-
// RUN: %clang_cl -fno-integrated-cc1 -E /experimental:deterministic /d1nodatetime %s
// RUN: %clang_cl -fno-integrated-cc1 -E /D IS_SYSHEADER=1 /experimental:deterministic /d1nodatetime %s
@@ -13,8 +11,9 @@
// RUN: %clang_cl -E -### /experimental:deterministic %s 2>&1 | FileCheck %s --check-prefix=WDATETIME
// WDATETIME: -Wdate-time
+// WDATETIME: -mno-incremental-linker-compatible
// RUN: %clang_cl -E -### /d1nodatetime %s 2>&1 | FileCheck %s --check-prefix=MACROREDEF
-// MACROREDEF: -Wno-builtin-macro-redefined
+// MACROREDEF: -init-datetime-macros=undefined
#ifdef IS_HEADER
diff --git a/clang/test/Preprocessor/init-datetime-macros.c b/clang/test/Preprocessor/init-datetime-macros.c
new file mode 100644
index 0000000000000..f12de677e2bc9
--- /dev/null
+++ b/clang/test/Preprocessor/init-datetime-macros.c
@@ -0,0 +1,60 @@
+// RUN: %clang_cc1 -E -DDATETIME_DEFAULT -init-datetime-macros=default %s | FileCheck %s --check-prefix CHECK-INIT-DATETIME-DEFAULT
+// RUN: %clang_cc1 -E -DDATETIME_DEFAULT %s | FileCheck %s --check-prefix CHECK-INIT-DATETIME-DEFAULT
+// CHECK-INIT-DATETIME-DEFAULT: date: "{{(Jan|Feb|Mar|Apr|May|Jun|Jul|Aug|Sep|Oct|Nov|Dec)}} {{.*}}"
+// CHECK-INIT-DATETIME-DEFAULT: time: "{{[0-9][0-9]:[0-9][0-9]:[0-9][0-9]}}"
+// CHECK-INIT-DATETIME-DEFAULT: timestamp: "{{.*}} {{[0-9][0-9]:[0-9][0-9]:[0-9][0-9]}} {{.*}}"
+// CHECK-INIT-DATETIME-DEFAULT-NOT: date:
+// CHECK-INIT-DATETIME-DEFAULT-NOT: time:
+// CHECK-INIT-DATETIME-DEFAULT-NOT: timestamp:
+
+// RUN: %clang_cc1 -E -DDATETIME_LITERALONE -init-datetime-macros=literalone %s | FileCheck %s --check-prefix CHECK-INIT-DATETIME-LITERALONE
+// CHECK-INIT-DATETIME-LITERALONE: date: "1"
+// CHECK-INIT-DATETIME-LITERALONE: time: "1"
+// CHECK-INIT-DATETIME-LITERALONE: timestamp: "1"
+// CHECK-INIT-DATETIME-LITERALONE-NOT: date:
+// CHECK-INIT-DATETIME-LITERALONE-NOT: time:
+// CHECK-INIT-DATETIME-LITERALONE-NOT: timestamp:
+
+// RUN: %clang_cc1 -E -DDATETIME_CUSTOM -init-datetime-macros=undefined -D__DATE__="\"d3\"" -D__TIME__="\"t4\"" -D__TIMESTAMP__="\"ts5\"" %s | FileCheck %s --check-prefix CHECK-INIT-DATETIME-CUSTOM
+// CHECK-INIT-DATETIME-CUSTOM: date: "d3"
+// CHECK-INIT-DATETIME-CUSTOM: time: "t4"
+// CHECK-INIT-DATETIME-CUSTOM: timestamp: "ts5"
+
+// RUN: %clang_cc1 -DDATETIME_UNDEFINED -verify -Wall -init-datetime-macros=undefined %s
+
+// clang-cl deterministic options checks:
+// /d1nodatetime - undefines __DATE__, __TIME__ and __TIMESTAMP__
+// /Brepro - sets __DATE__, __TIME__ and __TIMESTAMP__ to "1"
+
+// RUN: %clang_cl -Xclang -verify /d1nodatetime /DDATETIME_UNDEFINED /c %s
+
+// RUN: %clang_cl -E /Brepro /DDATETIME_LITERALONE /c %s | FileCheck %s --check-prefix CHECK-INIT-DATETIME-LITERALONE
+
+#if defined(DATETIME_LITERALONE) || defined(DATETIME_DEFAULT) || defined(DATETIME_CUSTOM)
+date: __DATE__
+time: __TIME__
+timestamp: __TIMESTAMP__
+#endif
+
+// Check we didn't break literal processing inside of PP macro expansion.
+#if defined(DATETIME_DEFAULT)
+#define CUST_DATE __DATE__
+#define CUST_TIME __TIME__
+#define CUST_TIMESTAMP __TIMESTAMP__
+const char *s0 = "CD: " CUST_DATE " CT: " CUST_TIME " CTS: " CUST_TIMESTAMP
+// CHECK-INIT-DATETIME-DEFAULT: const char *s0 = "CD: " "{{(Jan|Feb|Mar|Apr|May|Jun|Jul|Aug|Sep|Oct|Nov|Dec)}} {{.*}}" " CT: " "{{[0-9][0-9]:[0-9][0-9]:[0-9][0-9]}}" " CTS: " "{{.*}} {{[0-9][0-9]:[0-9][0-9]:[0-9][0-9]}} {{.*}}"
+#endif
+
+#if defined(DATETIME_LITERALONE)
+#define CUST_DATE __DATE__
+#define CUST_TIME __TIME__
+#define CUST_TIMESTAMP __TIMESTAMP__
+const char *s0 = "CD: " CUST_DATE " CT: " CUST_TIME " CTS: " CUST_TIMESTAMP
+// CHECK-INIT-DATETIME-LITERALONE: const char *s0 = "CD: " "1" " CT: " "1" " CTS: " "1"
+#endif
+
+#ifdef DATETIME_UNDEFINED
+const char *s1 = __DATE__; // expected-error{{use of undeclared identifier '__DATE__'}}
+const char *s2 = __TIME__; // expected-error{{use of undeclared identifier '__TIME__'}}
+const char *s3 = __TIMESTAMP__; // expected-error{{use of undeclared identifier '__TIMESTAMP__'}}
+#endif
>From 8baa3bcf6899bfe327a4ef1a90834c5ad8373c42 Mon Sep 17 00:00:00 2001
From: Vladimir Vereschaka <vvereschaka at accesssoftek.com>
Date: Tue, 19 May 2026 14:39:13 -0700
Subject: [PATCH 06/14] Updated formatting to pass the pre-commit tests.
---
clang/lib/Driver/ToolChains/Clang.cpp | 6 ++++--
clang/test/Driver/cl-deterministic.c | 3 ---
2 files changed, 4 insertions(+), 5 deletions(-)
diff --git a/clang/lib/Driver/ToolChains/Clang.cpp b/clang/lib/Driver/ToolChains/Clang.cpp
index 4ffb0acca56fb..8f28b46ea38a3 100644
--- a/clang/lib/Driver/ToolChains/Clang.cpp
+++ b/clang/lib/Driver/ToolChains/Clang.cpp
@@ -8912,14 +8912,16 @@ void Clang::AddClangCLArgs(const ArgList &Args, types::ID InputType,
}
if (Args.hasFlag(options::OPT__SLASH_d1nodatetime,
- options::OPT__SLASH_d1nodatetime_, false)) {
+ options::OPT__SLASH_d1nodatetime_, false)) {
CmdArgs.push_back("-init-datetime-macros=undefined");
}
// /Brepro is an alias for -mincremental-linker-compatible option.
if (!Args.hasFlag(options::OPT_mincremental_linker_compatible,
options::OPT_mno_incremental_linker_compatible,
- getToolChain().getTriple().isDefaultIncrementalLinkerCompatibleByDefault())) {
+ getToolChain()
+ .getTriple()
+ .isDefaultIncrementalLinkerCompatibleByDefault())) {
// Redefine the date/time macros only if /d1nodatetime wasn't specified.
// This options does not allow the user redifinitions for these macros.
if (!Args.hasFlag(options::OPT__SLASH_d1nodatetime,
diff --git a/clang/test/Driver/cl-deterministic.c b/clang/test/Driver/cl-deterministic.c
index 50ef612594f3e..2566641f2ceaa 100644
--- a/clang/test/Driver/cl-deterministic.c
+++ b/clang/test/Driver/cl-deterministic.c
@@ -1,6 +1,3 @@
-// We have to run the compilation step to see the output, so we must be able to
-// target Windows.
-
// RUN: %clang_cl -fno-integrated-cc1 -E /experimental:deterministic /d1nodatetime %s
// RUN: %clang_cl -fno-integrated-cc1 -E /D IS_SYSHEADER=1 /experimental:deterministic /d1nodatetime %s
>From 869243de803728b1a845e03ac3f23c1b75a51fe9 Mon Sep 17 00:00:00 2001
From: Vladimir Vereschaka <vvereschaka at accesssoftek.com>
Date: Tue, 19 May 2026 23:10:03 -0700
Subject: [PATCH 07/14] Add one more test case for
-init-datetime-macros=literalone.
Redefine macros from the command line.
---
clang/test/Preprocessor/init-datetime-macros.c | 1 +
1 file changed, 1 insertion(+)
diff --git a/clang/test/Preprocessor/init-datetime-macros.c b/clang/test/Preprocessor/init-datetime-macros.c
index f12de677e2bc9..19890102f6324 100644
--- a/clang/test/Preprocessor/init-datetime-macros.c
+++ b/clang/test/Preprocessor/init-datetime-macros.c
@@ -15,6 +15,7 @@
// CHECK-INIT-DATETIME-LITERALONE-NOT: time:
// CHECK-INIT-DATETIME-LITERALONE-NOT: timestamp:
+// RUN: %clang_cc1 -E -DDATETIME_CUSTOM -init-datetime-macros=literalone -D__DATE__="\"d3\"" -D__TIME__="\"t4\"" -D__TIMESTAMP__="\"ts5\"" %s | FileCheck %s --check-prefix CHECK-INIT-DATETIME-CUSTOM
// RUN: %clang_cc1 -E -DDATETIME_CUSTOM -init-datetime-macros=undefined -D__DATE__="\"d3\"" -D__TIME__="\"t4\"" -D__TIMESTAMP__="\"ts5\"" %s | FileCheck %s --check-prefix CHECK-INIT-DATETIME-CUSTOM
// CHECK-INIT-DATETIME-CUSTOM: date: "d3"
// CHECK-INIT-DATETIME-CUSTOM: time: "t4"
>From 8707915fdf1ba24798f46d2c3f7199d7c3d7758d Mon Sep 17 00:00:00 2001
From: Vladimir Vereschaka <vvereschaka at accesssoftek.com>
Date: Tue, 19 May 2026 23:13:17 -0700
Subject: [PATCH 08/14] Add newline at end of file
---
clang/test/Driver/cl-deterministic.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/clang/test/Driver/cl-deterministic.c b/clang/test/Driver/cl-deterministic.c
index 2566641f2ceaa..8ba8e9a17895b 100644
--- a/clang/test/Driver/cl-deterministic.c
+++ b/clang/test/Driver/cl-deterministic.c
@@ -29,4 +29,4 @@ __TIME__
#define IS_HEADER
#include __FILE__
-#endif
\ No newline at end of file
+#endif
>From 38f4eddd1166e6228ffb3fa75d009ae1892e2436 Mon Sep 17 00:00:00 2001
From: Vladimir Vereschaka <vvereschaka at accesssoftek.com>
Date: Wed, 10 Jun 2026 15:20:07 -0700
Subject: [PATCH 09/14] Update options::OPT__SLASH_d1nodatetime check.
---
clang/lib/Driver/ToolChains/Clang.cpp | 11 +++++------
1 file changed, 5 insertions(+), 6 deletions(-)
diff --git a/clang/lib/Driver/ToolChains/Clang.cpp b/clang/lib/Driver/ToolChains/Clang.cpp
index 8f28b46ea38a3..21a50286e76bb 100644
--- a/clang/lib/Driver/ToolChains/Clang.cpp
+++ b/clang/lib/Driver/ToolChains/Clang.cpp
@@ -8911,10 +8911,11 @@ void Clang::AddClangCLArgs(const ArgList &Args, types::ID InputType,
CmdArgs.push_back("-mno-incremental-linker-compatible");
}
- if (Args.hasFlag(options::OPT__SLASH_d1nodatetime,
- options::OPT__SLASH_d1nodatetime_, false)) {
+ bool HasNoDateTime = Args.hasFlag(options::OPT__SLASH_d1nodatetime,
+ options::OPT__SLASH_d1nodatetime_, false);
+
+ if (HasNoDateTime)
CmdArgs.push_back("-init-datetime-macros=undefined");
- }
// /Brepro is an alias for -mincremental-linker-compatible option.
if (!Args.hasFlag(options::OPT_mincremental_linker_compatible,
@@ -8924,10 +8925,8 @@ void Clang::AddClangCLArgs(const ArgList &Args, types::ID InputType,
.isDefaultIncrementalLinkerCompatibleByDefault())) {
// Redefine the date/time macros only if /d1nodatetime wasn't specified.
// This options does not allow the user redifinitions for these macros.
- if (!Args.hasFlag(options::OPT__SLASH_d1nodatetime,
- options::OPT__SLASH_d1nodatetime_, false)) {
+ if (!HasNoDateTime)
CmdArgs.push_back("-init-datetime-macros=literalone");
- }
}
}
>From 586b1add09add1473fb1fd2cca70421d9013399a Mon Sep 17 00:00:00 2001
From: Vladimir Vereschaka <vvereschaka at accesssoftek.com>
Date: Wed, 10 Jun 2026 16:41:25 -0700
Subject: [PATCH 10/14] Update `init-datetime-macros` test to run correctly on
Darwin.
---
clang/test/Preprocessor/init-datetime-macros.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/clang/test/Preprocessor/init-datetime-macros.c b/clang/test/Preprocessor/init-datetime-macros.c
index 19890102f6324..2a300bf80a648 100644
--- a/clang/test/Preprocessor/init-datetime-macros.c
+++ b/clang/test/Preprocessor/init-datetime-macros.c
@@ -27,9 +27,9 @@
// /d1nodatetime - undefines __DATE__, __TIME__ and __TIMESTAMP__
// /Brepro - sets __DATE__, __TIME__ and __TIMESTAMP__ to "1"
-// RUN: %clang_cl -Xclang -verify /d1nodatetime /DDATETIME_UNDEFINED /c %s
+// RUN: %clang_cl -Xclang -verify /d1nodatetime /DDATETIME_UNDEFINED /c -- %s
-// RUN: %clang_cl -E /Brepro /DDATETIME_LITERALONE /c %s | FileCheck %s --check-prefix CHECK-INIT-DATETIME-LITERALONE
+// RUN: %clang_cl -E /Brepro /DDATETIME_LITERALONE /c -- %s | FileCheck %s --check-prefix CHECK-INIT-DATETIME-LITERALONE
#if defined(DATETIME_LITERALONE) || defined(DATETIME_DEFAULT) || defined(DATETIME_CUSTOM)
date: __DATE__
>From a48b0fa2229ab5256fd231c9b6b2a9e906dfa894 Mon Sep 17 00:00:00 2001
From: Vladimir Vereschaka <vvereschaka at accesssoftek.com>
Date: Wed, 10 Jun 2026 17:02:05 -0700
Subject: [PATCH 11/14] Update `cl-deterministic` test to run correctly on
Darwin.
---
clang/test/Driver/cl-deterministic.c | 12 ++++++------
1 file changed, 6 insertions(+), 6 deletions(-)
diff --git a/clang/test/Driver/cl-deterministic.c b/clang/test/Driver/cl-deterministic.c
index 8ba8e9a17895b..3f6737b25ec08 100644
--- a/clang/test/Driver/cl-deterministic.c
+++ b/clang/test/Driver/cl-deterministic.c
@@ -1,15 +1,15 @@
-// RUN: %clang_cl -fno-integrated-cc1 -E /experimental:deterministic /d1nodatetime %s
-// RUN: %clang_cl -fno-integrated-cc1 -E /D IS_SYSHEADER=1 /experimental:deterministic /d1nodatetime %s
+// RUN: %clang_cl -fno-integrated-cc1 -E /experimental:deterministic /d1nodatetime -- %s
+// RUN: %clang_cl -fno-integrated-cc1 -E /D IS_SYSHEADER=1 /experimental:deterministic /d1nodatetime -- %s
-// RUN: %clang_cl -E /experimental:deterministic /d1nodatetime %s
-// RUN: %clang_cl -E /D IS_SYSHEADER=1 /experimental:deterministic /d1nodatetime %s
+// RUN: %clang_cl -E /experimental:deterministic /d1nodatetime -- %s
+// RUN: %clang_cl -E /D IS_SYSHEADER=1 /experimental:deterministic /d1nodatetime -- %s
// not %clang_cc1 -Werror=date-time -Wno-builtin-macro-redefined %s -DIS_SYSHEADER -E 2>&1 | grep 'error: expansion' | count 3
-// RUN: %clang_cl -E -### /experimental:deterministic %s 2>&1 | FileCheck %s --check-prefix=WDATETIME
+// RUN: %clang_cl -E -### /experimental:deterministic -- %s 2>&1 | FileCheck %s --check-prefix=WDATETIME
// WDATETIME: -Wdate-time
// WDATETIME: -mno-incremental-linker-compatible
-// RUN: %clang_cl -E -### /d1nodatetime %s 2>&1 | FileCheck %s --check-prefix=MACROREDEF
+// RUN: %clang_cl -E -### /d1nodatetime -- %s 2>&1 | FileCheck %s --check-prefix=MACROREDEF
// MACROREDEF: -init-datetime-macros=undefined
#ifdef IS_HEADER
>From ebf06be52bac66be076b8669354cabc3b752c48b Mon Sep 17 00:00:00 2001
From: Vladimir Vereschaka <vvereschaka at accesssoftek.com>
Date: Tue, 16 Jun 2026 18:54:32 -0700
Subject: [PATCH 12/14] Clean up and update `cl-deterministic.c` test.
---
clang/test/Driver/cl-deterministic.c | 8 ++++----
1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/clang/test/Driver/cl-deterministic.c b/clang/test/Driver/cl-deterministic.c
index 3f6737b25ec08..34010f24e53c2 100644
--- a/clang/test/Driver/cl-deterministic.c
+++ b/clang/test/Driver/cl-deterministic.c
@@ -4,7 +4,7 @@
// RUN: %clang_cl -E /experimental:deterministic /d1nodatetime -- %s
// RUN: %clang_cl -E /D IS_SYSHEADER=1 /experimental:deterministic /d1nodatetime -- %s
-// not %clang_cc1 -Werror=date-time -Wno-builtin-macro-redefined %s -DIS_SYSHEADER -E 2>&1 | grep 'error: expansion' | count 3
+// expected-no-diagnostics
// RUN: %clang_cl -E -### /experimental:deterministic -- %s 2>&1 | FileCheck %s --check-prefix=WDATETIME
// WDATETIME: -Wdate-time
@@ -18,9 +18,9 @@
#pragma clang system_header
#endif
-__TIME__ // expected-warning {{expansion of date or time macro is not reproducible}}
-__DATE__ // expected-warning {{expansion of date or time macro is not reproducible}}
-__TIMESTAMP__ // expected-warning {{expansion of date or time macro is not reproducible}}
+__TIME__
+__DATE__
+__TIMESTAMP__
#define __TIME__
__TIME__
>From 63ee96713612d0c04e84178a5e261cdfea0b9e68 Mon Sep 17 00:00:00 2001
From: Vladimir Vereschaka <vvereschaka at accesssoftek.com>
Date: Tue, 16 Jun 2026 18:58:14 -0700
Subject: [PATCH 13/14] Additional `init-datetime-macros-warns/nowarns` tests
to check ghe diagnostic messages.
---
clang/test/Preprocessor/init-datetime-macros-nowarns.c | 6 ++++++
clang/test/Preprocessor/init-datetime-macros-warns.c | 8 ++++++++
clang/test/Preprocessor/init-datetime-macros.c | 4 ++--
3 files changed, 16 insertions(+), 2 deletions(-)
create mode 100644 clang/test/Preprocessor/init-datetime-macros-nowarns.c
create mode 100644 clang/test/Preprocessor/init-datetime-macros-warns.c
diff --git a/clang/test/Preprocessor/init-datetime-macros-nowarns.c b/clang/test/Preprocessor/init-datetime-macros-nowarns.c
new file mode 100644
index 0000000000000..dbdaf8da425d6
--- /dev/null
+++ b/clang/test/Preprocessor/init-datetime-macros-nowarns.c
@@ -0,0 +1,6 @@
+// RUN: %clang_cc1 -E -DDATETIME_CUSTOM -init-datetime-macros=undefined -D__DATE__="\"d3\"" -D__TIME__="\"t4\"" -D__TIMESTAMP__="\"ts5\"" -verify %s
+// expected-no-diagnostics
+
+date: __DATE__
+time: __TIME__
+timestamp: __TIMESTAMP__
diff --git a/clang/test/Preprocessor/init-datetime-macros-warns.c b/clang/test/Preprocessor/init-datetime-macros-warns.c
new file mode 100644
index 0000000000000..b1f4c0376452d
--- /dev/null
+++ b/clang/test/Preprocessor/init-datetime-macros-warns.c
@@ -0,0 +1,8 @@
+// RUN: %clang_cc1 -E -DDATETIME_CUSTOM -init-datetime-macros=literalone -D__DATE__="\"d3\"" -D__TIME__="\"t4\"" -D__TIMESTAMP__="\"ts5\"" -verify %s
+// expected-warning at 2{{redefining builtin macro}}
+// expected-warning at 3{{redefining builtin macro}}
+// expected-warning at 4{{redefining builtin macro}}
+
+date: __DATE__
+time: __TIME__
+timestamp: __TIMESTAMP__
diff --git a/clang/test/Preprocessor/init-datetime-macros.c b/clang/test/Preprocessor/init-datetime-macros.c
index 2a300bf80a648..239bafd2b241e 100644
--- a/clang/test/Preprocessor/init-datetime-macros.c
+++ b/clang/test/Preprocessor/init-datetime-macros.c
@@ -15,7 +15,7 @@
// CHECK-INIT-DATETIME-LITERALONE-NOT: time:
// CHECK-INIT-DATETIME-LITERALONE-NOT: timestamp:
-// RUN: %clang_cc1 -E -DDATETIME_CUSTOM -init-datetime-macros=literalone -D__DATE__="\"d3\"" -D__TIME__="\"t4\"" -D__TIMESTAMP__="\"ts5\"" %s | FileCheck %s --check-prefix CHECK-INIT-DATETIME-CUSTOM
+// RUN: %clang_cc1 -E -DDATETIME_CUSTOM -init-datetime-macros=literalone -Wno-builtin-macro-redefined -D__DATE__="\"d3\"" -D__TIME__="\"t4\"" -D__TIMESTAMP__="\"ts5\"" %s | FileCheck %s --check-prefix CHECK-INIT-DATETIME-CUSTOM
// RUN: %clang_cc1 -E -DDATETIME_CUSTOM -init-datetime-macros=undefined -D__DATE__="\"d3\"" -D__TIME__="\"t4\"" -D__TIMESTAMP__="\"ts5\"" %s | FileCheck %s --check-prefix CHECK-INIT-DATETIME-CUSTOM
// CHECK-INIT-DATETIME-CUSTOM: date: "d3"
// CHECK-INIT-DATETIME-CUSTOM: time: "t4"
@@ -29,7 +29,7 @@
// RUN: %clang_cl -Xclang -verify /d1nodatetime /DDATETIME_UNDEFINED /c -- %s
-// RUN: %clang_cl -E /Brepro /DDATETIME_LITERALONE /c -- %s | FileCheck %s --check-prefix CHECK-INIT-DATETIME-LITERALONE
+// RUN: %clang_cl -E /Brepro /DDATETIME_LITERALONE -- %s | FileCheck %s --check-prefix CHECK-INIT-DATETIME-LITERALONE
#if defined(DATETIME_LITERALONE) || defined(DATETIME_DEFAULT) || defined(DATETIME_CUSTOM)
date: __DATE__
>From c9d2e84b63c188f11cc809b36f5ff45612f48a07 Mon Sep 17 00:00:00 2001
From: Vladimir Vereschaka <vvereschaka at accesssoftek.com>
Date: Tue, 16 Jun 2026 19:02:14 -0700
Subject: [PATCH 14/14] Fixed typos
---
clang/lib/Driver/ToolChains/Clang.cpp | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/clang/lib/Driver/ToolChains/Clang.cpp b/clang/lib/Driver/ToolChains/Clang.cpp
index 21a50286e76bb..59e6c7dd8e79c 100644
--- a/clang/lib/Driver/ToolChains/Clang.cpp
+++ b/clang/lib/Driver/ToolChains/Clang.cpp
@@ -8924,7 +8924,7 @@ void Clang::AddClangCLArgs(const ArgList &Args, types::ID InputType,
.getTriple()
.isDefaultIncrementalLinkerCompatibleByDefault())) {
// Redefine the date/time macros only if /d1nodatetime wasn't specified.
- // This options does not allow the user redifinitions for these macros.
+ // This option does not allow the user redefinitions for these macros.
if (!HasNoDateTime)
CmdArgs.push_back("-init-datetime-macros=literalone");
}
More information about the cfe-commits
mailing list