On 14/03/2023 16:50, Pádraig Brady wrote:
On 14/03/2023 13:55, Marcus Müller wrote:
Dear Gnulib community,

On Linux, x86_64, Fedora 37, ran, on today's coreutils' HEAD (e68b15), which 
submodule-includes gnulib f17d3977:

CFLAGS=-Wno-deprecated-declarations ./configure

(as that CFLAGS is necessary, otherwise sha will fail to build due to using 
deprecated functionality; no big issue).
However, building coreutils fails in gnulib and that does seem to be a 
significant bug:

make -j8 fails with

lib/nstrftime.c: In function '__strftime_internal':
lib/nstrftime.c:147:31: error: 'memset' specified size 18446744073709551615 
exceeds maximum object size 9223372036854775807 [-Werror=stringop-overflow=]

This is triggered by -O2 being implicitly removed when you specified the CFLAGS 
explicitly.
I.e. there are gcc false positives at lower optimization levels.

Actually different -Wmaybe-initialized warnings can trigger at various 
optimization levels.

Also you're building from git, and so will have more strict
developer appropriate warning settings by default
(which can be controlled with the --enable-gcc-warnings=no configure option).

In my experience of this particular "stringop-overflow" warning,
I've had to work around it so many times in a large build system in work
that I disabled it by default in the central build config.
It probably makes sense to disable this in the coreutils settings at least,
which is done in the attached.
The attached also addresses -Wmaybe-initialized warnings in coreutils
that show up at lower optimization levels.

I'm applying the two attached patches to coreutils to address these issues.

cheers,
Pádraig
From b4e20026a49297f024d399f1f49c58dc3134f82b Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?P=C3=A1draig=20Brady?= <p...@draigbrady.com>
Date: Thu, 18 May 2023 10:38:11 +0100
Subject: [PATCH 1/2] build: avoid incorrect -Wmaybe-uninitialized warnings

Allow easily building a debug build for example with:
  make CFLAGS='-O0 -ggdb'

False -Wmaybe-uninitialized warnings hit in different
places depending on the compiler passes used.
These changes were tested with gcc 10.2.1, 12.2.1, and 13.1.1 like:
  for o in g s z fast 0 1 2 3; do
    make clean && make -j$(nproc) CFLAGS="-O$o" || break
  done

* src/digest.c: Disable -Wmaybe-uninitialized that gives
false positive here at -O0.
* src/ln.c: Avoid -Wmaybe-uninitialized that gives
false positive here at -O1.
* src/pr.c: Likewise.
* src/sort.c: Likewise.
* src/tee.c: Avoid -Wmaybe-uninitialized that gives
false positive here at -O3 on gcc 13.1.1 at least.
* src/cp.c: Avoid -Wmaybe-uninitialized that gives
false positive here at -Os on gcc 13.1.1 at least.
* src/copy.c: Avoid -Wmaybe-uninitialized that gives
false positive here at -Og on gcc 13.1.1 at least.
* src/head.c: Likewise.
* src/paste.c: Likewise.
---
 src/copy.c   | 4 ++--
 src/cp.c     | 2 +-
 src/digest.c | 3 +++
 src/head.c   | 2 +-
 src/ln.c     | 2 +-
 src/paste.c  | 2 +-
 src/pr.c     | 2 +-
 src/sort.c   | 2 +-
 src/tee.c    | 2 +-
 9 files changed, 12 insertions(+), 9 deletions(-)

diff --git a/src/copy.c b/src/copy.c
index 0dd059d2e..6b2cf3b29 100644
--- a/src/copy.c
+++ b/src/copy.c
@@ -1238,8 +1238,8 @@ copy_reg (char const *src_name, char const *dst_name,
           struct stat const *src_sb)
 {
   char *buf = NULL;
-  int dest_desc;
-  int dest_errno;
+  int dest_desc IF_LINT ( = -1);
+  int dest_errno IF_LINT ( = 0);
   int source_desc;
   mode_t src_mode = src_sb->st_mode;
   mode_t extra_permissions;
diff --git a/src/cp.c b/src/cp.c
index 619eb8260..c952eb397 100644
--- a/src/cp.c
+++ b/src/cp.c
@@ -441,7 +441,7 @@ make_dir_parents_private (char const *const_dir, size_t src_offset,
 
       while ((slash = strchr (slash, '/')))
         {
-          struct dir_attr *new;
+          struct dir_attr *new IF_LINT ( = NULL);
           bool missing_dir;
 
           *slash = '\0';
diff --git a/src/digest.c b/src/digest.c
index ab32968db..8c483a425 100644
--- a/src/digest.c
+++ b/src/digest.c
@@ -1125,6 +1125,9 @@ hex_equal (unsigned char const *hex_digest, unsigned char const *bin_buffer)
   return cnt == digest_bin_bytes;
 }
 
+# if defined __GNUC__ && (__GNUC__ + (__GNUC_MINOR__ >= 7) > 4)
+#  pragma GCC diagnostic ignored "-Wmaybe-uninitialized"
+# endif
 static bool
 digest_check (char const *checkfile_name)
 {
diff --git a/src/head.c b/src/head.c
index c9d3b0d05..f576a2200 100644
--- a/src/head.c
+++ b/src/head.c
@@ -351,7 +351,7 @@ elide_tail_bytes_pipe (char const *filename, int fd, uintmax_t n_elide_0,
          bytes.  Then, for each new buffer we read, also write an old one.  */
 
       bool eof = false;
-      size_t n_read;
+      size_t n_read IF_LINT ( = 0);
       bool buffered_enough;
       size_t i, i_next;
       char **b = NULL;
diff --git a/src/ln.c b/src/ln.c
index 1c3307cac..bfdac0cd9 100644
--- a/src/ln.c
+++ b/src/ln.c
@@ -473,7 +473,7 @@ main (int argc, char **argv)
   char const *backup_suffix = NULL;
   char *version_control_string = NULL;
   char const *target_directory = NULL;
-  int destdir_fd;
+  int destdir_fd IF_LINT ( = -1);
   bool no_target_directory = false;
   int n_files;
   char **file;
diff --git a/src/paste.c b/src/paste.c
index 5c194d8fe..468ef3ab0 100644
--- a/src/paste.c
+++ b/src/paste.c
@@ -233,7 +233,7 @@ paste_parallel (size_t nfiles, char **fnamptr)
 
       for (size_t i = 0; i < nfiles && files_open; i++)
         {
-          int chr;			/* Input character. */
+          int chr IF_LINT ( = -1);	/* Input character. */
           int err;			/* Input errno value.  */
           bool sometodo = false;	/* Input chars to process.  */
 
diff --git a/src/pr.c b/src/pr.c
index 1c32e8c81..6be5b1f33 100644
--- a/src/pr.c
+++ b/src/pr.c
@@ -2428,7 +2428,7 @@ static bool
 read_line (COLUMN *p)
 {
   int c;
-  int chars;
+  int chars IF_LINT ( =0);
   int last_input_position;
   int j, k;
   COLUMN *q;
diff --git a/src/sort.c b/src/sort.c
index 8ca7a88c4..5aadc797b 100644
--- a/src/sort.c
+++ b/src/sort.c
@@ -1045,7 +1045,7 @@ pipe_fork (int pipefds[2], size_t tries)
   struct tempnode *saved_temphead;
   int saved_errno;
   double wait_retry = 0.25;
-  pid_t pid;
+  pid_t pid IF_LINT ( = -1);
   struct cs_status cs;
 
   if (pipe2 (pipefds, O_CLOEXEC) < 0)
diff --git a/src/tee.c b/src/tee.c
index a1c057816..27e83619e 100644
--- a/src/tee.c
+++ b/src/tee.c
@@ -228,7 +228,7 @@ tee_files (int nfiles, char **files, bool pipe_check)
 {
   size_t n_outputs = 0;
   FILE **descriptors;
-  bool *out_pollable;
+  bool *out_pollable IF_LINT ( = NULL);
   char buffer[BUFSIZ];
   ssize_t bytes_read = 0;
   int i;
-- 
2.40.1

From ffaba6e8afb2235f758bf4efdedf1441ed8eda8b Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?P=C3=A1draig=20Brady?= <p...@draigbrady.com>
Date: Thu, 18 May 2023 11:40:19 +0100
Subject: [PATCH 2/2] build: gnulib: avoid false -Wstringop-overflow warning

Tested on gcc 13.1.1 with: make CFLAGS='-O0 -ggdb'

* configure.ac: Disable -Wstringop-overflow for gnulib.
This warning is far too problematic in my experience:
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=88443
and triggers with gcc -O0 with versions 12,13 at least.
---
 configure.ac | 5 +++++
 1 file changed, 5 insertions(+)

diff --git a/configure.ac b/configure.ac
index f61076d2b..27e743157 100644
--- a/configure.ac
+++ b/configure.ac
@@ -261,6 +261,11 @@ if test $gl_gcc_warnings != no; then
   # FP in careadlinkat.c w/gcc 10.0.1 20200205
   gl_WARN_ADD([-Wno-return-local-addr])
 
+  # FIXME: remove this line when gcc improves
+  # https://gcc.gnu.org/bugzilla/show_bug.cgi?id=88443
+  # FP wth -O0 in nstrftime.c w/gcc 12, and 13 at least
+  gl_WARN_ADD([-Wno-stringop-overflow])
+
   gl_MANYWARN_COMPLEMENT([GNULIB_WARN_CFLAGS], [$WARN_CFLAGS], [$nw])
   AC_SUBST([GNULIB_WARN_CFLAGS])
 
-- 
2.40.1

Reply via email to