Subject: bug#51504: closed (Re: bug#51504: grep not building for me with gcc 11.2)

From: [email-masked] (GNU bug Tracking System)
Date: Sun, 31 Oct 2021 00:42:02 +0000

Your bug report

#51504: grep not building for me with gcc 11.2

which was filed against the grep package, has been closed.

The explanation is attached below, along with your original report.
If you require more details, please reply to [email-masked].

-- 
51504: http://debbugs.gnu.org/cgi/bugreport.cgi?bug=51504
GNU Bug Tracking System
Contact [email-masked] with problems

Subject: Re: bug#51504: grep not building for me with gcc 11.2
From: Paul Eggert <[email-masked]>
To: Duncan Roe <[email-masked]>
Cc: [email-masked], [email-masked]
Date: Sat, 30 Oct 2021 17:41:13 -0700
List-Id: <debbugs-submit.debbugs.gnu.org>

On 10/30/21 01:40, Duncan Roe wrote:
> To stop other folks running into this, configure.ac needs to be fixed to not
> --enable-gcc-warnings of its own accord.

configure.ac enables GCC warnings by default only you're building from a 
Git repository. If you had built from the latest grep release tarball 
you wouldn't have run into this problem.

This should be documented better in README-hacking. I installed a patch 
to GNU grep to try to do that. See:

https://git.savannah.gnu.org/cgit/grep.git/commit/?id=1ba972edec7867c1592083363dc9fadfebf77e2e

> Should I report these to the gcc team?

I wouldn't bother. The grep sources are tuned for --enable-gcc-warnings 
with -O2 and no other optimization-relevant options.

Subject: grep not building for me with gcc 11.2
From: Duncan Roe <[email-masked]>
To: [email-masked]
Cc: [email-masked], Duncan Roe <[email-masked]>
Date: Sat, 30 Oct 2021 19:40:25 +1100
List-Id: <debbugs-submit.debbugs.gnu.org>

Straight away let me say I have gotten around this and can now build grep. But
it toook me 2 days.

The actual bug is that `CFLAGS=` causes configure to enable gcc warnings. I
would then get multiline warnings like the one at end of this report. Because of
-Werror, the build would then stop.

I had been running configure as `CFLAGS='-g3 -ggdb' ./configure --disable-nls`.
Eventually I tried plain `./configure` which built. Tests revealed simply
`CFLAGS=-g ./configure` provokes the warnings. Now I run `CFLAGS='-g3 -ggdb'
./configure --disable-gcc-warnings --disable-nls`.

To stop other folks running into this, configure.ac needs to be fixed to not
--enable-gcc-warnings of its own accord.

Cheers ... Duncan.

========================================

All the "error" lines flagged by gcc11.2 are false alarms. This is a list of
them:
> exclude.c:691:10: error: leak of FILE 'in' [CWE-775] [-Werror=analyzer-file-leak]
> fts.c:1497:25: error: use of NULL 'cp' where non-null expected [CWE-476] [-Werror=analyzer-null-argument]
> regex_internal.c:992:17: error: dereference of possibly-NULL 'next_nodes.elems' [CWE-690] [-Werror=analyzer-possible-null-dereference]
> regex_internal.c:992:17: error: dereference of possibly-NULL '*dests_node.elems' [CWE-690] [-Werror=analyzer-possible-null-dereference]
> regex_internal.c:992:17: error: dereference of possibly-NULL 'union_set.elems' [CWE-690] [-Werror=analyzer-possible-null-dereference]
> regex_internal.c:992:17: error: dereference of possibly-NULL '*set.elems' [CWE-690] [-Werror=analyzer-possible-null-dereference]
> regex_internal.c:992:17: error: dereference of possibly-NULL '*set.elems' [CWE-690] [-Werror=analyzer-possible-null-dereference]
> regex_internal.c:992:17: error: dereference of possibly-NULL 'new_nodes.elems' [CWE-690] [-Werror=analyzer-possible-null-dereference]
> regex_internal.c:1040:7: error: use of possibly-NULL 'next_nodes.elems' where non-null expected [CWE-690] [-Werror=analyzer-possible-null-argument]
> regex_internal.c:1040:7: error: use of possibly-NULL '*dest.elems' where non-null expected [CWE-690] [-Werror=analyzer-possible-null-argument]

These are all in gnulib. The following patch eliminates all of them, but don't
apply it. The patch is to highlight code constructs that gcc can't analyse
adequately.

Should I report these to the gcc team? They tend to like simple sources with no
headers and so on - I don't know if I can find the time to do that. But maybe I
could do 1 or 2. At least it's their own source (gnu's, not gcc's).

========================================

Here's an analysis of the first alleged error. add_exclude_file() is a short
function:
> int
> add_exclude_file (void (*add_func) (struct exclude *, char const *, int),
>                   struct exclude *ex, char const *file_name, int options,
>                   char line_end)
> {
>   bool use_stdin = file_name[0] == '-' && !file_name[1];
>   FILE *in;
>   int rc = 0;
>
>   if (use_stdin)
>     in = stdin;
>   else if (! (in = fopen (file_name, "re")))
>     return -1;
>
>   rc = add_exclude_fp (call_addfn, ex, in, options, line_end, &add_func);
>
>   if (!use_stdin && fclose (in) != 0)
>     rc = -1;
>
>   return rc;
> }
If `use_stdin` is false then `in` becomes the fd of some file. But if
`use_stdin` is false, then `in` is rigorously closed. So there can be no file
leak.

> In function 'add_exclude_file':
> exclude.c:691:10: error: leak of FILE 'in' [CWE-775] [-Werror=analyzer-file-leak]
>   691 |   return rc;
>       |          ^~
>   'add_exclude_file': events 1-8
>     |
>     |  673 | add_exclude_file (void (*add_func) (struct exclude *, char const *, int),
>     |      | ^~~~~~~~~~~~~~~~
>     |      | |
>     |      | (1) entry to 'add_exclude_file'
>     |......
>     |  681 |   if (use_stdin)
>     |      |      ~
>     |      |      |
>     |      |      (2) following 'false' branch (when 'use_stdin == 0')...
>     |  682 |     in = stdin;
>     |  683 |   else if (! (in = fopen (file_name, "re")))
>     |      |           ~        ~~~~~~~~~~~~~~~~~~~~~~~
>     |      |           |        |
>     |      |           |        (3) ...to here
>     |      |           |        (4) opened here
>     |      |           (5) assuming 'in' is non-NULL
>     |      |           (6) following 'false' branch (when 'in' is non-NULL)...
>     |......
>     |  686 |   rc = add_exclude_fp (call_addfn, ex, in, options, line_end, &add_func);
>     |      |        ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
>     |      |        |
>     |      |        (7) ...to here
>     |      |        (8) calling 'add_exclude_fp' from 'add_exclude_file'
>     |
>     +--'add_exclude_fp': event 9
>            |
>            |  608 | add_exclude_fp (void (*add_func) (struct exclude *, char const *, int, void *),
>            |      | ^~~~~~~~~~~~~~
>            |      | |
>            |      | (9) entry to 'add_exclude_fp'
>            |
>          'add_exclude_fp': events 10-16
>            |
>            |  622 |   while ((c = getc (fp)) != EOF)
>            |      |                          ^
>            |      |                          |
>            |      |                          (10) following 'false' branch (when 'c == -1')...
>            |......
>            |  629 |   if (ferror (fp))
>            |      |       ~~~~~~~~~~~
>            |      |       |
>            |      |       (11) ...to here
>            |......
>            |  634 |   lim = buf + buf_count + ! (buf_count == 0 || buf[buf_count - 1] == line_end);
>            |      |                           ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
>            |      |                           |
>            |      |                           (12) following 'false' branch (when 'buf_count == 0')...
>            |      |                           (13) ...to here
>            |......
>            |  640 |   for (p = buf; p < lim; p++)
>            |      |                 ~~~~~~~
>            |      |                   |
>            |      |                   (16) following 'false' branch (when 'p >= lim')...
>            |  641 |     if (*p == line_end)
>            |      |        ~
>            |      |        |
>            |      |        (14) following 'true' branch...
>            |  642 |       {
>            |  643 |         char *pattern_end = p;
>            |      |               ~~~~~~~~~~~
>            |      |               |
>            |      |               (15) ...to here
>            |
>          'add_exclude_fp': event 17
>            |
>            |  661 |   errno = e;
>            |      |   ^~~~~
>            |      |   |
>            |      |   (17) ...to here
>            |
>     <------+
>     |
>   'add_exclude_file': events 18-21
>     |
>     |  686 |   rc = add_exclude_fp (call_addfn, ex, in, options, line_end, &add_func);
>     |      |        ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
>     |      |        |
>     |      |        (18) returning to 'add_exclude_file' from 'add_exclude_fp'
>     |  687 |
>     |  688 |   if (!use_stdin && fclose (in) != 0)
>     |      |      ~
>     |      |      |
>     |      |      (19) following 'false' branch...
>     |......
>     |  691 |   return rc;
>     |      |          ~~
>     |      |          |
>     |      |          (20) ...to here
>     |      |          (21) 'in' leaks here; was opened at (4)
>     |
> 13:51:11$ gcc --version
> gcc (GCC) 11.2.0

Duncan Roe (1):
  Silly patch to avoid some gcc 11.2 warnings

 lib/exclude.c        | 9 +++++++--
 lib/fts.c            | 2 +-
 lib/regex_internal.c | 6 +++---
 3 files changed, 11 insertions(+), 6 deletions(-)

-- 
2.33.1