gnu: emacs-consult: Fix grammar.
[jackhill/guix/guix.git] / gnu / packages / patches / gcc-5-source-date-epoch-1.patch
CommitLineData
d71d6fe8
MB
1Make GCC respect SOURCE_DATE_EPOCH in __DATE__ and __TIME__ macros.
2
3Patch adapted from upstream source repository:
4
5https://gcc.gnu.org/git/?p=gcc.git;a=commitdiff;h=e3e8c48c4a494d9da741c1c8ea6c4c0b7c4ff934
6
7From e3e8c48c4a494d9da741c1c8ea6c4c0b7c4ff934 Mon Sep 17 00:00:00 2001
8From: doko <doko@138bc75d-0d04-0410-961f-82ee72b054a4>
9Date: Thu, 28 Apr 2016 09:12:05 +0000
10Subject: [PATCH] gcc/c-family/ChangeLog:
11
12diff --git a/gcc/c-family/c-common.c b/gcc/c-family/c-common.c
13index 1bf5d080034..6f0898a38d7 100644
14--- a/gcc/c-family/c-common.c
15+++ b/gcc/c-family/c-common.c
16@@ -12318,4 +12318,37 @@ pointer_to_zero_sized_aggr_p (tree t)
17 return (TYPE_SIZE (t) && integer_zerop (TYPE_SIZE (t)));
18 }
19
20+/* Read SOURCE_DATE_EPOCH from environment to have a deterministic
21+ timestamp to replace embedded current dates to get reproducible
22+ results. Returns -1 if SOURCE_DATE_EPOCH is not defined. */
23+time_t
24+get_source_date_epoch ()
25+{
26+ char *source_date_epoch;
27+ long long epoch;
28+ char *endptr;
29+
30+ source_date_epoch = getenv ("SOURCE_DATE_EPOCH");
31+ if (!source_date_epoch)
32+ return (time_t) -1;
33+
34+ errno = 0;
35+ epoch = strtoll (source_date_epoch, &endptr, 10);
36+ if ((errno == ERANGE && (epoch == LLONG_MAX || epoch == LLONG_MIN))
37+ || (errno != 0 && epoch == 0))
38+ fatal_error (UNKNOWN_LOCATION, "environment variable $SOURCE_DATE_EPOCH: "
39+ "strtoll: %s\n", xstrerror(errno));
40+ if (endptr == source_date_epoch)
41+ fatal_error (UNKNOWN_LOCATION, "environment variable $SOURCE_DATE_EPOCH: "
42+ "no digits were found: %s\n", endptr);
43+ if (*endptr != '\0')
44+ fatal_error (UNKNOWN_LOCATION, "environment variable $SOURCE_DATE_EPOCH: "
45+ "trailing garbage: %s\n", endptr);
46+ if (epoch < 0)
47+ fatal_error (UNKNOWN_LOCATION, "environment variable $SOURCE_DATE_EPOCH: "
48+ "value must be nonnegative: %lld \n", epoch);
49+
50+ return (time_t) epoch;
51+}
52+
53 #include "gt-c-family-c-common.h"
54diff --git a/gcc/c-family/c-common.h b/gcc/c-family/c-common.h
55index fdb227f85c3..ba0a5d7df50 100644
56--- a/gcc/c-family/c-common.h
57+++ b/gcc/c-family/c-common.h
58@@ -1437,4 +1437,10 @@ extern bool contains_cilk_spawn_stmt (tree);
59 extern tree cilk_for_number_of_iterations (tree);
60 extern bool check_no_cilk (tree, const char *, const char *,
61 location_t loc = UNKNOWN_LOCATION);
62+
63+/* Read SOURCE_DATE_EPOCH from environment to have a deterministic
64+ timestamp to replace embedded current dates to get reproducible
65+ results. Returns -1 if SOURCE_DATE_EPOCH is not defined. */
66+extern time_t get_source_date_epoch (void);
67+
68 #endif /* ! GCC_C_COMMON_H */
69diff --git a/gcc/c-family/c-lex.c b/gcc/c-family/c-lex.c
70index bb55be8063e..e68471b9d2b 100644
71--- a/gcc/c-family/c-lex.c
72+++ b/gcc/c-family/c-lex.c
73@@ -402,6 +402,9 @@ c_lex_with_flags (tree *value, location_t *loc, unsigned char *cpp_flags,
74 enum cpp_ttype type;
75 unsigned char add_flags = 0;
76 enum overflow_type overflow = OT_NONE;
77+ time_t source_date_epoch = get_source_date_epoch ();
78+
79+ cpp_init_source_date_epoch (parse_in, source_date_epoch);
80
81 timevar_push (TV_CPP);
82 retry:
83diff --git a/gcc/doc/cppenv.texi b/gcc/doc/cppenv.texi
84index 100811dc637..3b5317beb53 100644
85--- a/gcc/doc/cppenv.texi
86+++ b/gcc/doc/cppenv.texi
87@@ -79,4 +79,21 @@ main input file is omitted.
88 @ifclear cppmanual
89 @xref{Preprocessor Options}.
90 @end ifclear
91+
92+@item SOURCE_DATE_EPOCH
93+
94+If this variable is set, its value specifies a UNIX timestamp to be
95+used in replacement of the current date and time in the @code{__DATE__}
96+and @code{__TIME__} macros, so that the embedded timestamps become
97+reproducible.
98+
99+The value of @env{SOURCE_DATE_EPOCH} must be a UNIX timestamp,
100+defined as the number of seconds (excluding leap seconds) since
101+01 Jan 1970 00:00:00 represented in ASCII, identical to the output of
102+@samp{@command{date +%s}}.
103+
104+The value should be a known timestamp such as the last modification
105+time of the source or package and it should be set by the build
106+process.
107+
108 @end vtable
109diff --git a/libcpp/include/cpplib.h b/libcpp/include/cpplib.h
110index 1b731d1a3ad..7a5481219be 100644
111--- a/libcpp/include/cpplib.h
112+++ b/libcpp/include/cpplib.h
113@@ -775,6 +775,9 @@ extern void cpp_init_special_builtins (cpp_reader *);
114 /* Set up built-ins like __FILE__. */
115 extern void cpp_init_builtins (cpp_reader *, int);
116
117+/* Initialize the source_date_epoch value. */
118+extern void cpp_init_source_date_epoch (cpp_reader *, time_t);
119+
120 /* This is called after options have been parsed, and partially
121 processed. */
122 extern void cpp_post_options (cpp_reader *);
123diff --git a/libcpp/init.c b/libcpp/init.c
124index 45a4d13ffa3..a8d00f4628b 100644
125--- a/libcpp/init.c
126+++ b/libcpp/init.c
127@@ -530,6 +530,13 @@ cpp_init_builtins (cpp_reader *pfile, int hosted)
128 _cpp_define_builtin (pfile, "__OBJC__ 1");
129 }
130
131+/* Initialize the source_date_epoch value. */
132+void
133+cpp_init_source_date_epoch (cpp_reader *pfile, time_t source_date_epoch)
134+{
135+ pfile->source_date_epoch = source_date_epoch;
136+}
137+
138 /* Sanity-checks are dependent on command-line options, so it is
139 called as a subroutine of cpp_read_main_file (). */
140 #if ENABLE_CHECKING
141diff --git a/libcpp/internal.h b/libcpp/internal.h
142index c2d08168945..8507eba1747 100644
143--- a/libcpp/internal.h
144+++ b/libcpp/internal.h
145@@ -502,6 +502,10 @@ struct cpp_reader
146 const unsigned char *date;
147 const unsigned char *time;
148
149+ /* Externally set timestamp to replace current date and time useful for
150+ reproducibility. */
151+ time_t source_date_epoch;
152+
153 /* EOF token, and a token forcing paste avoidance. */
154 cpp_token avoid_paste;
155 cpp_token eof;
156diff --git a/libcpp/macro.c b/libcpp/macro.c
157index eb32a6f8c98..3f3b278e97d 100644
158--- a/libcpp/macro.c
159+++ b/libcpp/macro.c
160@@ -350,13 +350,20 @@ _cpp_builtin_macro_text (cpp_reader *pfile, cpp_hashnode *node)
161 time_t tt;
162 struct tm *tb = NULL;
163
164- /* (time_t) -1 is a legitimate value for "number of seconds
165- since the Epoch", so we have to do a little dance to
166- distinguish that from a genuine error. */
167- errno = 0;
168- tt = time(NULL);
169- if (tt != (time_t)-1 || errno == 0)
170- tb = localtime (&tt);
171+ /* Set a reproducible timestamp for __DATE__ and __TIME__ macro
172+ usage if SOURCE_DATE_EPOCH is defined. */
173+ if (pfile->source_date_epoch != (time_t) -1)
174+ tb = gmtime (&pfile->source_date_epoch);
175+ else
176+ {
177+ /* (time_t) -1 is a legitimate value for "number of seconds
178+ since the Epoch", so we have to do a little dance to
179+ distinguish that from a genuine error. */
180+ errno = 0;
181+ tt = time (NULL);
182+ if (tt != (time_t)-1 || errno == 0)
183+ tb = localtime (&tt);
184+ }
185
186 if (tb)
187 {
188--
1892.11.0
190