Commit 15c98b2e by Eduard Sanou Committed by Matthias Klose

c-common.c (get_source_date_epoch): Rename to cb_get_source_date_epoch.

gcc/c-family/ChangeLog:

2016-05-13  Eduard Sanou  <dhole@openmailbox.org>

	* c-common.c (get_source_date_epoch): Rename to
	cb_get_source_date_epoch.
	* c-common.c (cb_get_source_date_epoch): Use a single generic erorr
	message when the parsing fails.  Use error_at instead of fatal_error.
	* c-common.h (get_source_date_epoch): Rename to
	cb_get_source_date_epoch.
	* c-common.h (cb_get_source_date_epoch): Prototype.
	* c-common.h (MAX_SOURCE_DATE_EPOCH): Define.
	* c-common.h (c_omp_region_type): Remove trailing comma.
	* c-lex.c (init_c_lex): Set cb->get_source_date_epoch callback.
	* c-lex.c (c_lex_with_flags): Remove initialization of
	pfile->source_date_epoch.

gcc/ChangeLog:

2016-05-13  Eduard Sanou  <dhole@openmailbox.org>

	* doc/cppenv.texi: Note that the `%s` in `date` is a non-standard
	extension.
	* gcc.c (driver_handle_option): Call set_source_date_epoch_envvar.
	* gcc.c (set_source_date_epoch_envvar): New function, sets
	the SOURCE_DATE_EPOCH environment variable to the current time.

gcc/testsuite/ChangeLog:

2016-05-13  Eduard Sanou  <dhole@openmailbox.org>

	* gcc.dg/cpp/source_date_epoch-1.c: New file, test the proper
	behaviour of the macros __DATE__ and __TIME__ when SOURCE_DATE_EPOCH
	env var is set.
	* gcc.dg/cpp/source_date_epoch-2.c: New file, test the error output
	when parsing the SOURCE_DATE_EPOCH env var, and make sure it is only
	shown once.
	* lib/gcc-dg.exp (dg-set-compiler-env-var): New function, set env vars
	during compilation.
	* lib/gcc-dg.exp (restore-compiler-env-var): New function, restore env
	vars set by dg-set-compiler-env-var.

libcpp/ChangeLog:

2016-05-13  Eduard Sanou  <dhole@openmailbox.org>

	* include/cpplib.h (cpp_callbacks): Add get_source_date_epoch
	callback.
	* include/cpplib.h (cpp_init_source_date_epoch): Remove prototype.
	* init.c (cpp_init_source_date_epoch): Remove function.
	* init.c (cpp_create_reader): Initialize pfile->source_date_epoch.
	* internal.h (cpp_reader): Extend comment about source_date_epoch.
	* macro.c (_cpp_builtin_macro_text): Use get_source_date_epoch
	callback only once, read pfile->source_date_epoch on future passes.
	Check that get_source_date_epoch callback is not NULL.

From-SVN: r237001
parent de482e91
2016-06-01 Eduard Sanou <dhole@openmailbox.org>
* doc/cppenv.texi: Note that the `%s` in `date` is a non-standard
extension.
* gcc.c (driver_handle_option): Call set_source_date_epoch_envvar.
* gcc.c (set_source_date_epoch_envvar): New function, sets
the SOURCE_DATE_EPOCH environment variable to the current time.
2016-06-01 Eric Botcazou <ebotcazou@adacore.com> 2016-06-01 Eric Botcazou <ebotcazou@adacore.com>
* tree-vect-loop.c (vect_determine_vectorization_factor): Also compute * tree-vect-loop.c (vect_determine_vectorization_factor): Also compute
......
2016-06-01 Eduard Sanou <dhole@openmailbox.org>
* c-common.c (get_source_date_epoch): Rename to
cb_get_source_date_epoch.
* c-common.c (cb_get_source_date_epoch): Use a single generic erorr
message when the parsing fails. Use error_at instead of fatal_error.
* c-common.h (get_source_date_epoch): Rename to
cb_get_source_date_epoch.
* c-common.h (cb_get_source_date_epoch): Prototype.
* c-common.h (MAX_SOURCE_DATE_EPOCH): Define.
* c-common.h (c_omp_region_type): Remove trailing comma.
* c-lex.c (init_c_lex): Set cb->get_source_date_epoch callback.
* c-lex.c (c_lex_with_flags): Remove initialization of
pfile->source_date_epoch.
2016-05-30 Jakub Jelinek <jakub@redhat.com> 2016-05-30 Jakub Jelinek <jakub@redhat.com>
PR c++/71349 PR c++/71349
......
...@@ -12762,8 +12762,9 @@ valid_array_size_p (location_t loc, tree type, tree name) ...@@ -12762,8 +12762,9 @@ valid_array_size_p (location_t loc, tree type, tree name)
/* Read SOURCE_DATE_EPOCH from environment to have a deterministic /* Read SOURCE_DATE_EPOCH from environment to have a deterministic
timestamp to replace embedded current dates to get reproducible timestamp to replace embedded current dates to get reproducible
results. Returns -1 if SOURCE_DATE_EPOCH is not defined. */ results. Returns -1 if SOURCE_DATE_EPOCH is not defined. */
time_t time_t
get_source_date_epoch () cb_get_source_date_epoch (cpp_reader *pfile ATTRIBUTE_UNUSED)
{ {
char *source_date_epoch; char *source_date_epoch;
long long epoch; long long epoch;
...@@ -12775,19 +12776,14 @@ get_source_date_epoch () ...@@ -12775,19 +12776,14 @@ get_source_date_epoch ()
errno = 0; errno = 0;
epoch = strtoll (source_date_epoch, &endptr, 10); epoch = strtoll (source_date_epoch, &endptr, 10);
if ((errno == ERANGE && (epoch == LLONG_MAX || epoch == LLONG_MIN)) if (errno != 0 || endptr == source_date_epoch || *endptr != '\0'
|| (errno != 0 && epoch == 0)) || epoch < 0 || epoch > MAX_SOURCE_DATE_EPOCH)
fatal_error (UNKNOWN_LOCATION, "environment variable $SOURCE_DATE_EPOCH: " {
"strtoll: %s\n", xstrerror(errno)); error_at (input_location, "environment variable SOURCE_DATE_EPOCH must "
if (endptr == source_date_epoch) "expand to a non-negative integer less than or equal to %wd",
fatal_error (UNKNOWN_LOCATION, "environment variable $SOURCE_DATE_EPOCH: " MAX_SOURCE_DATE_EPOCH);
"no digits were found: %s\n", endptr); return (time_t) -1;
if (*endptr != '\0') }
fatal_error (UNKNOWN_LOCATION, "environment variable $SOURCE_DATE_EPOCH: "
"trailing garbage: %s\n", endptr);
if (epoch < 0)
fatal_error (UNKNOWN_LOCATION, "environment variable $SOURCE_DATE_EPOCH: "
"value must be nonnegative: %lld \n", epoch);
return (time_t) epoch; return (time_t) epoch;
} }
......
...@@ -1088,6 +1088,16 @@ extern vec<tree, va_gc> *make_tree_vector_copy (const vec<tree, va_gc> *); ...@@ -1088,6 +1088,16 @@ extern vec<tree, va_gc> *make_tree_vector_copy (const vec<tree, va_gc> *);
c_register_builtin_type. */ c_register_builtin_type. */
extern GTY(()) tree registered_builtin_types; extern GTY(()) tree registered_builtin_types;
/* Read SOURCE_DATE_EPOCH from environment to have a deterministic
timestamp to replace embedded current dates to get reproducible
results. Returns -1 if SOURCE_DATE_EPOCH is not defined. */
extern time_t cb_get_source_date_epoch (cpp_reader *pfile);
/* The value (as a unix timestamp) corresponds to date
"Dec 31 9999 23:59:59 UTC", which is the latest date that __DATE__ and
__TIME__ can store. */
#define MAX_SOURCE_DATE_EPOCH HOST_WIDE_INT_C (253402300799)
/* In c-gimplify.c */ /* In c-gimplify.c */
extern void c_genericize (tree); extern void c_genericize (tree);
extern int c_gimplify_expr (tree *, gimple_seq *, gimple_seq *); extern int c_gimplify_expr (tree *, gimple_seq *, gimple_seq *);
...@@ -1482,9 +1492,4 @@ extern bool valid_array_size_p (location_t, tree, tree); ...@@ -1482,9 +1492,4 @@ extern bool valid_array_size_p (location_t, tree, tree);
extern bool cilk_ignorable_spawn_rhs_op (tree); extern bool cilk_ignorable_spawn_rhs_op (tree);
extern bool cilk_recognize_spawn (tree, tree *); extern bool cilk_recognize_spawn (tree, tree *);
/* Read SOURCE_DATE_EPOCH from environment to have a deterministic
timestamp to replace embedded current dates to get reproducible
results. Returns -1 if SOURCE_DATE_EPOCH is not defined. */
extern time_t get_source_date_epoch (void);
#endif /* ! GCC_C_COMMON_H */ #endif /* ! GCC_C_COMMON_H */
...@@ -80,6 +80,7 @@ init_c_lex (void) ...@@ -80,6 +80,7 @@ init_c_lex (void)
cb->valid_pch = c_common_valid_pch; cb->valid_pch = c_common_valid_pch;
cb->read_pch = c_common_read_pch; cb->read_pch = c_common_read_pch;
cb->has_attribute = c_common_has_attribute; cb->has_attribute = c_common_has_attribute;
cb->get_source_date_epoch = cb_get_source_date_epoch;
/* Set the debug callbacks if we can use them. */ /* Set the debug callbacks if we can use them. */
if ((debug_info_level == DINFO_LEVEL_VERBOSE if ((debug_info_level == DINFO_LEVEL_VERBOSE
...@@ -389,9 +390,6 @@ c_lex_with_flags (tree *value, location_t *loc, unsigned char *cpp_flags, ...@@ -389,9 +390,6 @@ c_lex_with_flags (tree *value, location_t *loc, unsigned char *cpp_flags,
enum cpp_ttype type; enum cpp_ttype type;
unsigned char add_flags = 0; unsigned char add_flags = 0;
enum overflow_type overflow = OT_NONE; enum overflow_type overflow = OT_NONE;
time_t source_date_epoch = get_source_date_epoch ();
cpp_init_source_date_epoch (parse_in, source_date_epoch);
timevar_push (TV_CPP); timevar_push (TV_CPP);
retry: retry:
......
...@@ -81,7 +81,6 @@ main input file is omitted. ...@@ -81,7 +81,6 @@ main input file is omitted.
@end ifclear @end ifclear
@item SOURCE_DATE_EPOCH @item SOURCE_DATE_EPOCH
If this variable is set, its value specifies a UNIX timestamp to be If this variable is set, its value specifies a UNIX timestamp to be
used in replacement of the current date and time in the @code{__DATE__} used in replacement of the current date and time in the @code{__DATE__}
and @code{__TIME__} macros, so that the embedded timestamps become and @code{__TIME__} macros, so that the embedded timestamps become
...@@ -89,8 +88,9 @@ reproducible. ...@@ -89,8 +88,9 @@ reproducible.
The value of @env{SOURCE_DATE_EPOCH} must be a UNIX timestamp, The value of @env{SOURCE_DATE_EPOCH} must be a UNIX timestamp,
defined as the number of seconds (excluding leap seconds) since defined as the number of seconds (excluding leap seconds) since
01 Jan 1970 00:00:00 represented in ASCII, identical to the output of 01 Jan 1970 00:00:00 represented in ASCII; identical to the output of
@samp{@command{date +%s}}. @samp{@command{date +%s}} on GNU/Linux and other systems that support the
@code{%s} extension in the @code{date} command.
The value should be a known timestamp such as the last modification The value should be a known timestamp such as the last modification
time of the source or package and it should be set by the build time of the source or package and it should be set by the build
......
...@@ -3547,6 +3547,29 @@ save_switch (const char *opt, size_t n_args, const char *const *args, ...@@ -3547,6 +3547,29 @@ save_switch (const char *opt, size_t n_args, const char *const *args,
n_switches++; n_switches++;
} }
/* Set the SOURCE_DATE_EPOCH environment variable to the current time if it is
not set already. */
static void
set_source_date_epoch_envvar ()
{
/* Array size is 21 = ceil(log_10(2^64)) + 1 to hold string representations
of 64 bit integers. */
char source_date_epoch[21];
time_t tt;
errno = 0;
tt = time (NULL);
if (tt < (time_t) 0 || errno != 0)
tt = (time_t) 0;
snprintf (source_date_epoch, 21, "%llu", (unsigned long long) tt);
/* Using setenv instead of xputenv because we want the variable to remain
after finalizing so that it's still set in the second run when using
-fcompare-debug. */
setenv ("SOURCE_DATE_EPOCH", source_date_epoch, 0);
}
/* Handle an option DECODED that is unknown to the option-processing /* Handle an option DECODED that is unknown to the option-processing
machinery. */ machinery. */
...@@ -3846,6 +3869,7 @@ driver_handle_option (struct gcc_options *opts, ...@@ -3846,6 +3869,7 @@ driver_handle_option (struct gcc_options *opts,
else else
compare_debug_opt = arg; compare_debug_opt = arg;
save_switch (compare_debug_replacement_opt, 0, NULL, validated, true); save_switch (compare_debug_replacement_opt, 0, NULL, validated, true);
set_source_date_epoch_envvar ();
return true; return true;
case OPT_fdiagnostics_color_: case OPT_fdiagnostics_color_:
......
2016-06-01 Eduard Sanou <dhole@openmailbox.org>
* gcc.dg/cpp/source_date_epoch-1.c: New file, test the proper
behaviour of the macros __DATE__ and __TIME__ when SOURCE_DATE_EPOCH
env var is set.
* gcc.dg/cpp/source_date_epoch-2.c: New file, test the error output
when parsing the SOURCE_DATE_EPOCH env var, and make sure it is only
shown once.
* lib/gcc-dg.exp (dg-set-compiler-env-var): New function, set env vars
during compilation.
* lib/gcc-dg.exp (restore-compiler-env-var): New function, restore env
vars set by dg-set-compiler-env-var.
2016-06-01 Paul Thomas <pault@gcc.gnu.org> 2016-06-01 Paul Thomas <pault@gcc.gnu.org>
PR fortran/71156 PR fortran/71156
......
/* { dg-do run } */
/* { dg-set-compiler-env-var SOURCE_DATE_EPOCH "630333296" } */
int
main(void)
{
__builtin_printf ("%s %s\n", __DATE__, __TIME__);
return 0;
}
/* { dg-output "^Dec 22 1989 12:34:56\n$" } */
/* { dg-do compile } */
/* { dg-set-compiler-env-var SOURCE_DATE_EPOCH "AAA" } */
/* Make sure that SOURCE_DATE_EPOCH is only parsed once */
int
main(void)
{
__builtin_printf ("%s %s\n", __DATE__, __TIME__); /* { dg-error "SOURCE_DATE_EPOCH must expand" } */
__builtin_printf ("%s %s\n", __DATE__, __TIME__);
return 0;
}
...@@ -451,6 +451,38 @@ proc restore-target-env-var { } { ...@@ -451,6 +451,38 @@ proc restore-target-env-var { } {
} }
} }
proc dg-set-compiler-env-var { args } {
global set_compiler_env_var
global saved_compiler_env_var
if { [llength $args] != 3 } {
error "dg-set-compiler-env-var: need two arguments"
return
}
set var [lindex $args 1]
set value [lindex $args 2]
if [info exists ::env($var)] {
lappend saved_compiler_env_var [list $var 1 $::env($var)]
} else {
lappend saved_compiler_env_var [list $var 0]
}
setenv $var $value
lappend set_compiler_env_var [list $var $value]
}
proc restore-compiler-env-var { } {
global saved_compiler_env_var
for { set env_vari [llength $saved_compiler_env_var] } {
[incr env_vari -1] >= 0 } {} {
set env_var [lindex $saved_compiler_env_var $env_vari]
set var [lindex $env_var 0]
if [lindex $env_var 1] {
setenv $var [lindex $env_var 2]
} else {
unsetenv $var
}
}
}
# Utility routines. # Utility routines.
# #
...@@ -874,6 +906,11 @@ if { [info procs saved-dg-test] == [list] } { ...@@ -874,6 +906,11 @@ if { [info procs saved-dg-test] == [list] } {
if [info exists set_target_env_var] { if [info exists set_target_env_var] {
unset set_target_env_var unset set_target_env_var
} }
if [info exists set_compiler_env_var] {
restore-compiler-env-var
unset set_compiler_env_var
unset saved_compiler_env_var
}
if [info exists keep_saved_temps_suffixes] { if [info exists keep_saved_temps_suffixes] {
unset keep_saved_temps_suffixes unset keep_saved_temps_suffixes
} }
......
2016-06-01 Eduard Sanou <dhole@openmailbox.org>
* include/cpplib.h (cpp_callbacks): Add get_source_date_epoch
callback.
* include/cpplib.h (cpp_init_source_date_epoch): Remove prototype.
* init.c (cpp_init_source_date_epoch): Remove function.
* init.c (cpp_create_reader): Initialize pfile->source_date_epoch.
* internal.h (cpp_reader): Extend comment about source_date_epoch.
* macro.c (_cpp_builtin_macro_text): Use get_source_date_epoch
callback only once, read pfile->source_date_epoch on future passes.
Check that get_source_date_epoch callback is not NULL.
2016-05-20 Martin Liska <mliska@suse.cz> 2016-05-20 Martin Liska <mliska@suse.cz>
* config.in: Regenerated. * config.in: Regenerated.
......
...@@ -594,6 +594,9 @@ struct cpp_callbacks ...@@ -594,6 +594,9 @@ struct cpp_callbacks
/* Callback that can change a user builtin into normal macro. */ /* Callback that can change a user builtin into normal macro. */
bool (*user_builtin_macro) (cpp_reader *, cpp_hashnode *); bool (*user_builtin_macro) (cpp_reader *, cpp_hashnode *);
/* Callback to parse SOURCE_DATE_EPOCH from environment. */
time_t (*get_source_date_epoch) (cpp_reader *);
}; };
#ifdef VMS #ifdef VMS
...@@ -784,9 +787,6 @@ extern void cpp_init_special_builtins (cpp_reader *); ...@@ -784,9 +787,6 @@ extern void cpp_init_special_builtins (cpp_reader *);
/* Set up built-ins like __FILE__. */ /* Set up built-ins like __FILE__. */
extern void cpp_init_builtins (cpp_reader *, int); extern void cpp_init_builtins (cpp_reader *, int);
/* Initialize the source_date_epoch value. */
extern void cpp_init_source_date_epoch (cpp_reader *, time_t);
/* This is called after options have been parsed, and partially /* This is called after options have been parsed, and partially
processed. */ processed. */
extern void cpp_post_options (cpp_reader *); extern void cpp_post_options (cpp_reader *);
......
...@@ -257,6 +257,9 @@ cpp_create_reader (enum c_lang lang, cpp_hash_table *table, ...@@ -257,6 +257,9 @@ cpp_create_reader (enum c_lang lang, cpp_hash_table *table,
/* Do not force token locations by default. */ /* Do not force token locations by default. */
pfile->forced_token_location_p = NULL; pfile->forced_token_location_p = NULL;
/* Initialize source_date_epoch to -2 (not yet set). */
pfile->source_date_epoch = (time_t) -2;
/* The expression parser stack. */ /* The expression parser stack. */
_cpp_expand_op_stack (pfile); _cpp_expand_op_stack (pfile);
...@@ -533,13 +536,6 @@ cpp_init_builtins (cpp_reader *pfile, int hosted) ...@@ -533,13 +536,6 @@ cpp_init_builtins (cpp_reader *pfile, int hosted)
_cpp_define_builtin (pfile, "__OBJC__ 1"); _cpp_define_builtin (pfile, "__OBJC__ 1");
} }
/* Initialize the source_date_epoch value. */
void
cpp_init_source_date_epoch (cpp_reader *pfile, time_t source_date_epoch)
{
pfile->source_date_epoch = source_date_epoch;
}
/* Sanity-checks are dependent on command-line options, so it is /* Sanity-checks are dependent on command-line options, so it is
called as a subroutine of cpp_read_main_file. */ called as a subroutine of cpp_read_main_file. */
#if CHECKING_P #if CHECKING_P
......
...@@ -503,7 +503,8 @@ struct cpp_reader ...@@ -503,7 +503,8 @@ struct cpp_reader
const unsigned char *time; const unsigned char *time;
/* Externally set timestamp to replace current date and time useful for /* Externally set timestamp to replace current date and time useful for
reproducibility. */ reproducibility. It should be initialized to -2 (not yet set) and
set to -1 to disable it or to a non-negative value to enable it. */
time_t source_date_epoch; time_t source_date_epoch;
/* EOF token, and a token forcing paste avoidance. */ /* EOF token, and a token forcing paste avoidance. */
......
...@@ -358,9 +358,13 @@ _cpp_builtin_macro_text (cpp_reader *pfile, cpp_hashnode *node, ...@@ -358,9 +358,13 @@ _cpp_builtin_macro_text (cpp_reader *pfile, cpp_hashnode *node,
struct tm *tb = NULL; struct tm *tb = NULL;
/* Set a reproducible timestamp for __DATE__ and __TIME__ macro /* Set a reproducible timestamp for __DATE__ and __TIME__ macro
usage if SOURCE_DATE_EPOCH is defined. */ if SOURCE_DATE_EPOCH is defined. */
if (pfile->source_date_epoch != (time_t) -1) if (pfile->source_date_epoch == (time_t) -2
tb = gmtime (&pfile->source_date_epoch); && pfile->cb.get_source_date_epoch != NULL)
pfile->source_date_epoch = pfile->cb.get_source_date_epoch (pfile);
if (pfile->source_date_epoch >= (time_t) 0)
tb = gmtime (&pfile->source_date_epoch);
else else
{ {
/* (time_t) -1 is a legitimate value for "number of seconds /* (time_t) -1 is a legitimate value for "number of seconds
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment