Tobias Burnus wrote:
Gerald Pfeifer wrote:
To make it easier to reproduce builds of software and entire GNU/Linux
distributions, RMS had the idea of adding a warning to GCC that warns
about the use of __DATE__ and __TIME__.
I assume that he also likes to have a warning for __TIMESTAMP__.
I was thinking a new warning -Wdate-time or similar could address
this. Any volunteers implementing this?
Do you mean something like the attached patch? (Only lightly tested.)
Updated version attached – after bootstrapping and regtesting on
x86-64-gnu-linux
OK?
Tobias
2013-11-04 Tobias Burnus <bur...@net-b.de>
gcc/c-family/
* c.opt (-Wdate-time): New option
* c-opts.c (sanitize_cpp_opts): Pass on to libcpp.
gcc/
* doc/invoke.texi (-Wdate-time): Document.
gcc/fortran
* lang.opt (-Wdate-time): New option
* cpp.c (gfc_cpp_option_data): Add warn_date_time.
(gfc_cpp_init_options, gfc_cpp_handle_option,
gfc_cpp_post_options): Handle it and pass on to libcpp.
gcc/testsuite/
* g++.dg/warn/wdate-time.C: New.
* gcc.dg/wdate-time.c: New.
* gfortran.dg/wdate-time.F90: New.
libcpp/
* include/cpplib.h (CPP_W_DATE_TIME): Added.
(cpp_options): Add warn_date_time.
* init.c (cpp_create_reader): Init it.
* macro.c (_cpp_builtin_macro_text): Warn when
__DATE__/__TIME__/__TIMESTAMP__ is used.
diff --git a/gcc/c-family/c-opts.c b/gcc/c-family/c-opts.c
index 702fe1a..2de5425 100644
--- a/gcc/c-family/c-opts.c
+++ b/gcc/c-family/c-opts.c
@@ -1198,6 +1198,7 @@ sanitize_cpp_opts (void)
cpp_opts->unsigned_char = !flag_signed_char;
cpp_opts->stdc_0_in_system_headers = STDC_0_IN_SYSTEM_HEADERS;
+ cpp_opts->warn_date_time = cpp_warn_date_time;
/* Wlong-long is disabled by default. It is enabled by:
[-Wpedantic | -Wtraditional] -std=[gnu|c]++98 ; or
diff --git a/gcc/c-family/c.opt b/gcc/c-family/c.opt
index b862eb9..a5fe595 100644
--- a/gcc/c-family/c.opt
+++ b/gcc/c-family/c.opt
@@ -640,6 +640,10 @@ Wpragmas
C ObjC C++ ObjC++ Var(warn_pragmas) Init(1) Warning
Warn about misuses of pragmas
+Wdate-time
+Common Var(cpp_warn_date_time) Warning
+Warn about __TIME__, __DATE__ and __TIMESTAMP__ usage
+
Wproperty-assign-default
ObjC ObjC++ Var(warn_property_assign_default) Init(1) Warning
Warn if a property for an Objective-C object has no assign semantics specified
diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi
index e84bca3..5dae1fb 100644
--- a/gcc/doc/invoke.texi
+++ b/gcc/doc/invoke.texi
@@ -240,7 +240,7 @@ Objective-C and Objective-C++ Dialects}.
-Wno-attributes -Wno-builtin-macro-redefined @gol
-Wc++-compat -Wc++11-compat -Wcast-align -Wcast-qual @gol
-Wchar-subscripts -Wclobbered -Wcomment -Wconditionally-supported @gol
--Wconversion -Wcoverage-mismatch -Wdelete-incomplete -Wno-cpp @gol
+-Wconversion -Wcoverage-mismatch -Wdate-time -Wdelete-incomplete -Wno-cpp @gol
-Wno-deprecated -Wno-deprecated-declarations -Wdisabled-optimization @gol
-Wno-div-by-zero -Wdouble-promotion -Wempty-body -Wenum-compare @gol
-Wno-endif-labels -Werror -Werror=* @gol
@@ -4517,6 +4517,13 @@ types. @option{-Wconversion-null} is enabled by default.
Warn when a literal '0' is used as null pointer constant. This can
be useful to facilitate the conversion to @code{nullptr} in C++11.
+@item -Wdate-time
+@opindex Wdate-time
+@opindex Wno-date-time
+Warn when macros @code{__TIME__}, @code{__DATE__} or @code{__TIMESTAMP__}
+are encountered as they might prevent bit-wise-identical reproducable
+compilations.
+
@item -Wdelete-incomplete @r{(C++ and Objective-C++ only)}
@opindex Wdelete-incomplete
@opindex Wno-delete-incomplete
diff --git a/gcc/fortran/cpp.c b/gcc/fortran/cpp.c
index ea53681..8417ddc 100644
--- a/gcc/fortran/cpp.c
+++ b/gcc/fortran/cpp.c
@@ -100,6 +100,7 @@ struct gfc_cpp_option_data
const char *deps_filename_user; /* -MF <arg> */
int deps_missing_are_generated; /* -MG */
int deps_phony; /* -MP */
+ int warn_date_time; /* -Wdate-time */
const char *multilib; /* -imultilib <dir> */
const char *prefix; /* -iprefix <dir> */
@@ -262,6 +263,7 @@ gfc_cpp_init_options (unsigned int decoded_options_count,
gfc_cpp_option.no_predefined = 0;
gfc_cpp_option.standard_include_paths = 1;
gfc_cpp_option.verbose = 0;
+ gfc_cpp_option.warn_date_time = 0;
gfc_cpp_option.deps = 0;
gfc_cpp_option.deps_skip_system = 0;
gfc_cpp_option.deps_phony = 0;
@@ -359,6 +361,9 @@ gfc_cpp_handle_option (size_t scode, const char *arg, int value ATTRIBUTE_UNUSED
gfc_cpp_option.verbose = value;
break;
+ case OPT_Wdate_time:
+ gfc_cpp_option.warn_date_time = value;
+
case OPT_A:
case OPT_D:
case OPT_U:
@@ -469,6 +474,7 @@ gfc_cpp_post_options (void)
cpp_option->discard_comments_in_macro_exp = gfc_cpp_option.discard_comments_in_macro_exp;
cpp_option->print_include_names = gfc_cpp_option.print_include_names;
cpp_option->preprocessed = gfc_option.flag_preprocessed;
+ cpp_option->warn_date_time = gfc_cpp_option.warn_date_time;
if (gfc_cpp_makedep ())
{
diff --git a/gcc/fortran/lang.opt b/gcc/fortran/lang.opt
index 4f79934..5e09cbd 100644
--- a/gcc/fortran/lang.opt
+++ b/gcc/fortran/lang.opt
@@ -213,6 +213,10 @@ Wc-binding-type
Fortran Warning
Warn if the type of a variable might be not interoperable with C
+Wdate-time
+Fortran
+; Documented in C
+
Wcharacter-truncation
Fortran Warning
Warn about truncated character expressions
diff --git a/gcc/testsuite/g++.dg/warn/wdate-time.C b/gcc/testsuite/g++.dg/warn/wdate-time.C
new file mode 100644
index 0000000..040dd99
--- /dev/null
+++ b/gcc/testsuite/g++.dg/warn/wdate-time.C
@@ -0,0 +1,6 @@
+/* { dg-do compile } */
+/* { dg-options "-Wdate-time" } */
+
+const char time[] = __TIME__; /* { dg-warning "might prevent reproduce builds" } */
+const char date[] = __DATE__; /* { dg-warning "might prevent reproduce builds" } */
+const char timestamp[] = __TIMESTAMP__; /* { dg-warning "might prevent reproduce builds" } */
diff --git a/gcc/testsuite/gcc.dg/wdate-time.c b/gcc/testsuite/gcc.dg/wdate-time.c
new file mode 100644
index 0000000..040dd99
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/wdate-time.c
@@ -0,0 +1,6 @@
+/* { dg-do compile } */
+/* { dg-options "-Wdate-time" } */
+
+const char time[] = __TIME__; /* { dg-warning "might prevent reproduce builds" } */
+const char date[] = __DATE__; /* { dg-warning "might prevent reproduce builds" } */
+const char timestamp[] = __TIMESTAMP__; /* { dg-warning "might prevent reproduce builds" } */
diff --git a/gcc/testsuite/gfortran.dg/wdate-time.F90 b/gcc/testsuite/gfortran.dg/wdate-time.F90
new file mode 100644
index 0000000..f3a4f46
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/wdate-time.F90
@@ -0,0 +1,6 @@
+! { dg-do compile }
+! { dg-options "-Wdate-time" }
+print *, __TIMESTAMP__ ! { dg-warning "might prevent reproduce builds" }
+print *, __TIME__ ! { dg-warning "might prevent reproduce builds" }
+print *, __DATE__ ! { dg-warning "might prevent reproduce builds" }
+end
diff --git a/libcpp/include/cpplib.h b/libcpp/include/cpplib.h
index 34ad6c3..02927d4 100644
--- a/libcpp/include/cpplib.h
+++ b/libcpp/include/cpplib.h
@@ -337,6 +337,9 @@ struct cpp_options
/* Nonzero means warn if slash-star appears in a comment. */
unsigned char warn_comments;
+ /* Nonzero means to warn about __DATA__, __TIME__ and __TIMESTAMP__ usage. */
+ unsigned char warn_date_time;
+
/* Nonzero means warn if a user-supplied include directory does not
exist. */
unsigned char warn_missing_include_dirs;
@@ -925,7 +928,8 @@ enum {
CPP_W_NORMALIZE,
CPP_W_INVALID_PCH,
CPP_W_WARNING_DIRECTIVE,
- CPP_W_LITERAL_SUFFIX
+ CPP_W_LITERAL_SUFFIX,
+ CPP_W_DATE_TIME
};
/* Output a diagnostic of some kind. */
diff --git a/libcpp/init.c b/libcpp/init.c
index 97aa6cd..6744430 100644
--- a/libcpp/init.c
+++ b/libcpp/init.c
@@ -193,6 +193,7 @@ cpp_create_reader (enum c_lang lang, cpp_hash_table *table,
CPP_OPTION (pfile, canonical_system_headers)
= ENABLE_CANONICAL_SYSTEM_HEADERS;
CPP_OPTION (pfile, ext_numeric_literals) = 1;
+ CPP_OPTION (pfile, warn_date_time) = 0;
/* Default CPP arithmetic to something sensible for the host for the
benefit of dumb users like fix-header. */
diff --git a/libcpp/macro.c b/libcpp/macro.c
index 6d46027..3a1728d 100644
--- a/libcpp/macro.c
+++ b/libcpp/macro.c
@@ -232,6 +232,10 @@ _cpp_builtin_macro_text (cpp_reader *pfile, cpp_hashnode *node)
case BT_TIMESTAMP:
{
+ if (CPP_OPTION (pfile, warn_date_time))
+ cpp_warning (pfile, CPP_W_DATE_TIME, "Macro \"%s\" might prevent "
+ "reproduce builds", NODE_NAME (node));
+
cpp_buffer *pbuffer = cpp_get_buffer (pfile);
if (pbuffer->timestamp == NULL)
{
@@ -325,6 +329,9 @@ _cpp_builtin_macro_text (cpp_reader *pfile, cpp_hashnode *node)
case BT_DATE:
case BT_TIME:
+ if (CPP_OPTION (pfile, warn_date_time))
+ cpp_warning (pfile, CPP_W_DATE_TIME, "Macro \"%s\" might prevent "
+ "reproduce builds", NODE_NAME (node));
if (pfile->date == NULL)
{
/* Allocate __DATE__ and __TIME__ strings from permanent