Commit | Line | Data |
---|---|---|
aace9be8 MB |
1 | Cherry-picked from upstream commit: |
2 | ||
3 | https://gcc.gnu.org/git/?p=gcc.git;a=commitdiff;h=dfa5c0d3f3e23e4fdb14857a42de376d9ff8601c | |
4 | ||
5 | diff --git a/gcc/c-family/c-common.c b/gcc/c-family/c-common.c | |
6 | index b5daea65ba7..a4539da15ce 100644 | |
7 | --- a/gcc/c-family/c-common.c | |
8 | +++ b/gcc/c-family/c-common.c | |
9 | @@ -12753,8 +12753,9 @@ valid_array_size_p (location_t loc, tree type, tree name) | |
10 | /* Read SOURCE_DATE_EPOCH from environment to have a deterministic | |
11 | timestamp to replace embedded current dates to get reproducible | |
12 | results. Returns -1 if SOURCE_DATE_EPOCH is not defined. */ | |
13 | + | |
14 | time_t | |
15 | -get_source_date_epoch () | |
16 | +cb_get_source_date_epoch (cpp_reader *pfile ATTRIBUTE_UNUSED) | |
17 | { | |
18 | char *source_date_epoch; | |
19 | long long epoch; | |
20 | @@ -12766,19 +12767,14 @@ get_source_date_epoch () | |
21 | ||
22 | errno = 0; | |
23 | epoch = strtoll (source_date_epoch, &endptr, 10); | |
24 | - if ((errno == ERANGE && (epoch == LLONG_MAX || epoch == LLONG_MIN)) | |
25 | - || (errno != 0 && epoch == 0)) | |
26 | - fatal_error (UNKNOWN_LOCATION, "environment variable $SOURCE_DATE_EPOCH: " | |
27 | - "strtoll: %s\n", xstrerror(errno)); | |
28 | - if (endptr == source_date_epoch) | |
29 | - fatal_error (UNKNOWN_LOCATION, "environment variable $SOURCE_DATE_EPOCH: " | |
30 | - "no digits were found: %s\n", endptr); | |
31 | - if (*endptr != '\0') | |
32 | - fatal_error (UNKNOWN_LOCATION, "environment variable $SOURCE_DATE_EPOCH: " | |
33 | - "trailing garbage: %s\n", endptr); | |
34 | - if (epoch < 0) | |
35 | - fatal_error (UNKNOWN_LOCATION, "environment variable $SOURCE_DATE_EPOCH: " | |
36 | - "value must be nonnegative: %lld \n", epoch); | |
37 | + if (errno != 0 || endptr == source_date_epoch || *endptr != '\0' | |
38 | + || epoch < 0 || epoch > MAX_SOURCE_DATE_EPOCH) | |
39 | + { | |
40 | + error_at (input_location, "environment variable SOURCE_DATE_EPOCH must " | |
41 | + "expand to a non-negative integer less than or equal to %wd", | |
42 | + MAX_SOURCE_DATE_EPOCH); | |
43 | + return (time_t) -1; | |
44 | + } | |
45 | ||
46 | return (time_t) epoch; | |
47 | } | |
48 | diff --git a/gcc/c-family/c-common.h b/gcc/c-family/c-common.h | |
49 | index c6e0ed12b55..44699f716e0 100644 | |
50 | --- a/gcc/c-family/c-common.h | |
51 | +++ b/gcc/c-family/c-common.h | |
52 | @@ -1084,6 +1084,16 @@ extern vec<tree, va_gc> *make_tree_vector_copy (const vec<tree, va_gc> *); | |
53 | c_register_builtin_type. */ | |
54 | extern GTY(()) tree registered_builtin_types; | |
55 | ||
56 | +/* Read SOURCE_DATE_EPOCH from environment to have a deterministic | |
57 | + timestamp to replace embedded current dates to get reproducible | |
58 | + results. Returns -1 if SOURCE_DATE_EPOCH is not defined. */ | |
59 | +extern time_t cb_get_source_date_epoch (cpp_reader *pfile); | |
60 | + | |
61 | +/* The value (as a unix timestamp) corresponds to date | |
62 | + "Dec 31 9999 23:59:59 UTC", which is the latest date that __DATE__ and | |
63 | + __TIME__ can store. */ | |
64 | +#define MAX_SOURCE_DATE_EPOCH HOST_WIDE_INT_C (253402300799) | |
65 | + | |
66 | /* In c-gimplify.c */ | |
67 | extern void c_genericize (tree); | |
68 | extern int c_gimplify_expr (tree *, gimple_seq *, gimple_seq *); | |
69 | @@ -1467,9 +1477,4 @@ extern bool reject_gcc_builtin (const_tree, location_t = UNKNOWN_LOCATION); | |
70 | extern void warn_duplicated_cond_add_or_warn (location_t, tree, vec<tree> **); | |
71 | extern bool valid_array_size_p (location_t, tree, tree); | |
72 | ||
73 | -/* Read SOURCE_DATE_EPOCH from environment to have a deterministic | |
74 | - timestamp to replace embedded current dates to get reproducible | |
75 | - results. Returns -1 if SOURCE_DATE_EPOCH is not defined. */ | |
76 | -extern time_t get_source_date_epoch (void); | |
77 | - | |
78 | #endif /* ! GCC_C_COMMON_H */ | |
79 | diff --git a/gcc/c-family/c-lex.c b/gcc/c-family/c-lex.c | |
80 | index bf1db6c0252..42a4135d339 100644 | |
81 | --- a/gcc/c-family/c-lex.c | |
82 | +++ b/gcc/c-family/c-lex.c | |
83 | @@ -80,6 +80,7 @@ init_c_lex (void) | |
84 | cb->valid_pch = c_common_valid_pch; | |
85 | cb->read_pch = c_common_read_pch; | |
86 | cb->has_attribute = c_common_has_attribute; | |
87 | + cb->get_source_date_epoch = cb_get_source_date_epoch; | |
88 | ||
89 | /* Set the debug callbacks if we can use them. */ | |
90 | if ((debug_info_level == DINFO_LEVEL_VERBOSE | |
91 | @@ -385,9 +386,6 @@ c_lex_with_flags (tree *value, location_t *loc, unsigned char *cpp_flags, | |
92 | enum cpp_ttype type; | |
93 | unsigned char add_flags = 0; | |
94 | enum overflow_type overflow = OT_NONE; | |
95 | - time_t source_date_epoch = get_source_date_epoch (); | |
96 | - | |
97 | - cpp_init_source_date_epoch (parse_in, source_date_epoch); | |
98 | ||
99 | timevar_push (TV_CPP); | |
100 | retry: | |
101 | diff --git a/gcc/doc/cppenv.texi b/gcc/doc/cppenv.texi | |
102 | index e958e93e97e..8cefd529aa3 100644 | |
103 | --- a/gcc/doc/cppenv.texi | |
104 | +++ b/gcc/doc/cppenv.texi | |
105 | @@ -81,7 +81,6 @@ main input file is omitted. | |
106 | @end ifclear | |
107 | ||
108 | @item SOURCE_DATE_EPOCH | |
109 | - | |
110 | If this variable is set, its value specifies a UNIX timestamp to be | |
111 | used in replacement of the current date and time in the @code{__DATE__} | |
112 | and @code{__TIME__} macros, so that the embedded timestamps become | |
113 | @@ -89,8 +88,9 @@ reproducible. | |
114 | ||
115 | The value of @env{SOURCE_DATE_EPOCH} must be a UNIX timestamp, | |
116 | defined as the number of seconds (excluding leap seconds) since | |
117 | -01 Jan 1970 00:00:00 represented in ASCII, identical to the output of | |
118 | -@samp{@command{date +%s}}. | |
119 | +01 Jan 1970 00:00:00 represented in ASCII; identical to the output of | |
120 | +@samp{@command{date +%s}} on GNU/Linux and other systems that support the | |
121 | +@code{%s} extension in the @code{date} command. | |
122 | ||
123 | The value should be a known timestamp such as the last modification | |
124 | time of the source or package and it should be set by the build | |
125 | diff --git a/gcc/gcc.c b/gcc/gcc.c | |
126 | index cfa074d4e43..f88596219bc 100644 | |
127 | --- a/gcc/gcc.c | |
128 | +++ b/gcc/gcc.c | |
129 | @@ -3541,6 +3541,29 @@ save_switch (const char *opt, size_t n_args, const char *const *args, | |
130 | n_switches++; | |
131 | } | |
132 | ||
133 | +/* Set the SOURCE_DATE_EPOCH environment variable to the current time if it is | |
134 | + not set already. */ | |
135 | + | |
136 | +static void | |
137 | +set_source_date_epoch_envvar () | |
138 | +{ | |
139 | + /* Array size is 21 = ceil(log_10(2^64)) + 1 to hold string representations | |
140 | + of 64 bit integers. */ | |
141 | + char source_date_epoch[21]; | |
142 | + time_t tt; | |
143 | + | |
144 | + errno = 0; | |
145 | + tt = time (NULL); | |
146 | + if (tt < (time_t) 0 || errno != 0) | |
147 | + tt = (time_t) 0; | |
148 | + | |
149 | + snprintf (source_date_epoch, 21, "%llu", (unsigned long long) tt); | |
150 | + /* Using setenv instead of xputenv because we want the variable to remain | |
151 | + after finalizing so that it's still set in the second run when using | |
152 | + -fcompare-debug. */ | |
153 | + setenv ("SOURCE_DATE_EPOCH", source_date_epoch, 0); | |
154 | +} | |
155 | + | |
156 | /* Handle an option DECODED that is unknown to the option-processing | |
157 | machinery. */ | |
158 | ||
159 | @@ -3840,6 +3863,7 @@ driver_handle_option (struct gcc_options *opts, | |
160 | else | |
161 | compare_debug_opt = arg; | |
162 | save_switch (compare_debug_replacement_opt, 0, NULL, validated, true); | |
163 | + set_source_date_epoch_envvar (); | |
164 | return true; | |
165 | ||
166 | case OPT_fdiagnostics_color_: | |
167 | diff --git a/gcc/testsuite/gcc.dg/cpp/source_date_epoch-1.c b/gcc/testsuite/gcc.dg/cpp/source_date_epoch-1.c | |
168 | new file mode 100644 | |
169 | index 00000000000..f6aa1a360ff | |
170 | --- /dev/null | |
171 | +++ b/gcc/testsuite/gcc.dg/cpp/source_date_epoch-1.c | |
172 | @@ -0,0 +1,11 @@ | |
173 | +/* { dg-do run } */ | |
174 | +/* { dg-set-compiler-env-var SOURCE_DATE_EPOCH "630333296" } */ | |
175 | + | |
176 | +int | |
177 | +main(void) | |
178 | +{ | |
179 | + __builtin_printf ("%s %s\n", __DATE__, __TIME__); | |
180 | + return 0; | |
181 | +} | |
182 | + | |
183 | +/* { dg-output "^Dec 22 1989 12:34:56\n$" } */ | |
184 | diff --git a/gcc/testsuite/gcc.dg/cpp/source_date_epoch-2.c b/gcc/testsuite/gcc.dg/cpp/source_date_epoch-2.c | |
185 | new file mode 100644 | |
186 | index 00000000000..ae18362ae87 | |
187 | --- /dev/null | |
188 | +++ b/gcc/testsuite/gcc.dg/cpp/source_date_epoch-2.c | |
189 | @@ -0,0 +1,12 @@ | |
190 | +/* { dg-do compile } */ | |
191 | +/* { dg-set-compiler-env-var SOURCE_DATE_EPOCH "AAA" } */ | |
192 | + | |
193 | +/* Make sure that SOURCE_DATE_EPOCH is only parsed once */ | |
194 | + | |
195 | +int | |
196 | +main(void) | |
197 | +{ | |
198 | + __builtin_printf ("%s %s\n", __DATE__, __TIME__); /* { dg-error "SOURCE_DATE_EPOCH must expand" } */ | |
199 | + __builtin_printf ("%s %s\n", __DATE__, __TIME__); | |
200 | + return 0; | |
201 | +} | |
202 | diff --git a/gcc/testsuite/lib/gcc-dg.exp b/gcc/testsuite/lib/gcc-dg.exp | |
203 | index 9dd909b0985..822d2fbb3b9 100644 | |
204 | --- a/gcc/testsuite/lib/gcc-dg.exp | |
205 | +++ b/gcc/testsuite/lib/gcc-dg.exp | |
206 | @@ -450,6 +450,38 @@ proc restore-target-env-var { } { | |
207 | } | |
208 | } | |
209 | ||
210 | +proc dg-set-compiler-env-var { args } { | |
211 | + global set_compiler_env_var | |
212 | + global saved_compiler_env_var | |
213 | + if { [llength $args] != 3 } { | |
214 | + error "dg-set-compiler-env-var: need two arguments" | |
215 | + return | |
216 | + } | |
217 | + set var [lindex $args 1] | |
218 | + set value [lindex $args 2] | |
219 | + if [info exists ::env($var)] { | |
220 | + lappend saved_compiler_env_var [list $var 1 $::env($var)] | |
221 | + } else { | |
222 | + lappend saved_compiler_env_var [list $var 0] | |
223 | + } | |
224 | + setenv $var $value | |
225 | + lappend set_compiler_env_var [list $var $value] | |
226 | +} | |
227 | + | |
228 | +proc restore-compiler-env-var { } { | |
229 | + global saved_compiler_env_var | |
230 | + for { set env_vari [llength $saved_compiler_env_var] } { | |
231 | + [incr env_vari -1] >= 0 } {} { | |
232 | + set env_var [lindex $saved_compiler_env_var $env_vari] | |
233 | + set var [lindex $env_var 0] | |
234 | + if [lindex $env_var 1] { | |
235 | + setenv $var [lindex $env_var 2] | |
236 | + } else { | |
237 | + unsetenv $var | |
238 | + } | |
239 | + } | |
240 | +} | |
241 | + | |
242 | # Utility routines. | |
243 | ||
244 | # | |
245 | @@ -873,6 +905,11 @@ if { [info procs saved-dg-test] == [list] } { | |
246 | if [info exists set_target_env_var] { | |
247 | unset set_target_env_var | |
248 | } | |
249 | + if [info exists set_compiler_env_var] { | |
250 | + restore-compiler-env-var | |
251 | + unset set_compiler_env_var | |
252 | + unset saved_compiler_env_var | |
253 | + } | |
254 | if [info exists keep_saved_temps_suffixes] { | |
255 | unset keep_saved_temps_suffixes | |
256 | } | |
257 | diff --git a/libcpp/include/cpplib.h b/libcpp/include/cpplib.h | |
258 | index 4998b3a8ab8..9d70cc856ef 100644 | |
259 | --- a/libcpp/include/cpplib.h | |
260 | +++ b/libcpp/include/cpplib.h | |
261 | @@ -594,6 +594,9 @@ struct cpp_callbacks | |
262 | ||
263 | /* Callback that can change a user builtin into normal macro. */ | |
264 | bool (*user_builtin_macro) (cpp_reader *, cpp_hashnode *); | |
265 | + | |
266 | + /* Callback to parse SOURCE_DATE_EPOCH from environment. */ | |
267 | + time_t (*get_source_date_epoch) (cpp_reader *); | |
268 | }; | |
269 | ||
270 | #ifdef VMS | |
271 | @@ -784,9 +787,6 @@ extern void cpp_init_special_builtins (cpp_reader *); | |
272 | /* Set up built-ins like __FILE__. */ | |
273 | extern void cpp_init_builtins (cpp_reader *, int); | |
274 | ||
275 | -/* Initialize the source_date_epoch value. */ | |
276 | -extern void cpp_init_source_date_epoch (cpp_reader *, time_t); | |
277 | - | |
278 | /* This is called after options have been parsed, and partially | |
279 | processed. */ | |
280 | extern void cpp_post_options (cpp_reader *); | |
281 | diff --git a/libcpp/init.c b/libcpp/init.c | |
282 | index f5ff85b3bae..e78b3206def 100644 | |
283 | --- a/libcpp/init.c | |
284 | +++ b/libcpp/init.c | |
285 | @@ -257,6 +257,9 @@ cpp_create_reader (enum c_lang lang, cpp_hash_table *table, | |
286 | /* Do not force token locations by default. */ | |
287 | pfile->forced_token_location_p = NULL; | |
288 | ||
289 | + /* Initialize source_date_epoch to -2 (not yet set). */ | |
290 | + pfile->source_date_epoch = (time_t) -2; | |
291 | + | |
292 | /* The expression parser stack. */ | |
293 | _cpp_expand_op_stack (pfile); | |
294 | ||
295 | @@ -533,13 +536,6 @@ cpp_init_builtins (cpp_reader *pfile, int hosted) | |
296 | _cpp_define_builtin (pfile, "__OBJC__ 1"); | |
297 | } | |
298 | ||
299 | -/* Initialize the source_date_epoch value. */ | |
300 | -void | |
301 | -cpp_init_source_date_epoch (cpp_reader *pfile, time_t source_date_epoch) | |
302 | -{ | |
303 | - pfile->source_date_epoch = source_date_epoch; | |
304 | -} | |
305 | - | |
306 | /* Sanity-checks are dependent on command-line options, so it is | |
307 | called as a subroutine of cpp_read_main_file. */ | |
308 | #if CHECKING_P | |
309 | diff --git a/libcpp/internal.h b/libcpp/internal.h | |
310 | index e3eb26b1f27..cea32ec73c6 100644 | |
311 | --- a/libcpp/internal.h | |
312 | +++ b/libcpp/internal.h | |
313 | @@ -503,7 +503,8 @@ struct cpp_reader | |
314 | const unsigned char *time; | |
315 | ||
316 | /* Externally set timestamp to replace current date and time useful for | |
317 | - reproducibility. */ | |
318 | + reproducibility. It should be initialized to -2 (not yet set) and | |
319 | + set to -1 to disable it or to a non-negative value to enable it. */ | |
320 | time_t source_date_epoch; | |
321 | ||
322 | /* EOF token, and a token forcing paste avoidance. */ | |
323 | diff --git a/libcpp/macro.c b/libcpp/macro.c | |
324 | index c2a83764660..a3b8348a23f 100644 | |
325 | --- a/libcpp/macro.c | |
326 | +++ b/libcpp/macro.c | |
327 | @@ -358,9 +358,13 @@ _cpp_builtin_macro_text (cpp_reader *pfile, cpp_hashnode *node, | |
328 | struct tm *tb = NULL; | |
329 | ||
330 | /* Set a reproducible timestamp for __DATE__ and __TIME__ macro | |
331 | - usage if SOURCE_DATE_EPOCH is defined. */ | |
332 | - if (pfile->source_date_epoch != (time_t) -1) | |
333 | - tb = gmtime (&pfile->source_date_epoch); | |
334 | + if SOURCE_DATE_EPOCH is defined. */ | |
335 | + if (pfile->source_date_epoch == (time_t) -2 | |
336 | + && pfile->cb.get_source_date_epoch != NULL) | |
337 | + pfile->source_date_epoch = pfile->cb.get_source_date_epoch (pfile); | |
338 | + | |
339 | + if (pfile->source_date_epoch >= (time_t) 0) | |
340 | + tb = gmtime (&pfile->source_date_epoch); | |
341 | else | |
342 | { | |
343 | /* (time_t) -1 is a legitimate value for "number of seconds | |
344 | -- | |
345 | 2.14.1 | |
346 |