aboutsummaryrefslogtreecommitdiff
path: root/clang/lib/Frontend/CompilerInvocation.cpp
diff options
context:
space:
mode:
authorFangrui Song <i@maskray.me>2022-10-12 11:55:26 -0700
committerFangrui Song <i@maskray.me>2022-10-12 11:55:27 -0700
commit2c090162746a6b901c5639562c090e4bb2b7327e (patch)
treed65ca5b0b9c9e655a653f6156c847632c9e02639 /clang/lib/Frontend/CompilerInvocation.cpp
parente18b7c7ae0c13909d7f1304aee8621781a3c27a0 (diff)
downloadllvm-2c090162746a6b901c5639562c090e4bb2b7327e.zip
llvm-2c090162746a6b901c5639562c090e4bb2b7327e.tar.gz
llvm-2c090162746a6b901c5639562c090e4bb2b7327e.tar.bz2
[Frontend] Recognize environment variable SOURCE_DATE_EPOCH
See https://reproducible-builds.org/docs/source-date-epoch/ . The environment variable ``SOURCE_DATE_EPOCH`` been recognized by many compilers. In GCC, if `SOURCE_DATE_EPOCH` is set, it specifies a UNIX timestamp to be used in replacement of the current date and time in the `__DATE__` and `__TIME__` macros. Note: GCC as of today does not update `__TIMESTAMP__` (the modification time of the current source file) but https://wiki.debian.org/ReproducibleBuilds/TimestampsFromCPPMacros expresses the intention to update it. This patches parses SOURCE_DATE_EPOCH and changes all the three macros. In addition, in case gmtime/localtime returns null (e.g. on 64-bit Windows gmtime returns null when the timestamp is larger than 32536850399 (3001-01-19T21:59:59Z)), use `??? ?? ????` as used by GCC. Reviewed By: ychen Differential Revision: https://reviews.llvm.org/D135045
Diffstat (limited to 'clang/lib/Frontend/CompilerInvocation.cpp')
-rw-r--r--clang/lib/Frontend/CompilerInvocation.cpp17
1 files changed, 17 insertions, 0 deletions
diff --git a/clang/lib/Frontend/CompilerInvocation.cpp b/clang/lib/Frontend/CompilerInvocation.cpp
index 656e595..bcd5359 100644
--- a/clang/lib/Frontend/CompilerInvocation.cpp
+++ b/clang/lib/Frontend/CompilerInvocation.cpp
@@ -94,7 +94,9 @@
#include <cassert>
#include <cstddef>
#include <cstring>
+#include <ctime>
#include <fstream>
+#include <limits>
#include <memory>
#include <string>
#include <tuple>
@@ -4307,6 +4309,21 @@ static bool ParsePreprocessorArgs(PreprocessorOptions &Opts, ArgList &Args,
Opts.addRemappedFile(Split.first, Split.second);
}
+ if (const char *Epoch = std::getenv("SOURCE_DATE_EPOCH")) {
+ // SOURCE_DATE_EPOCH, if specified, must be a non-negative decimal integer.
+ // On time64 systems, pick 253402300799 (the UNIX timestamp of
+ // 9999-12-31T23:59:59Z) as the upper bound.
+ const uint64_t MaxTimestamp =
+ std::min<uint64_t>(std::numeric_limits<time_t>::max(), 253402300799);
+ uint64_t V;
+ if (StringRef(Epoch).getAsInteger(10, V) || V > MaxTimestamp) {
+ Diags.Report(diag::err_fe_invalid_source_date_epoch)
+ << Epoch << MaxTimestamp;
+ } else {
+ Opts.SourceDateEpoch = V;
+ }
+ }
+
// Always avoid lexing editor placeholders when we're just running the
// preprocessor as we never want to emit the
// "editor placeholder in source file" error in PP only mode.