emacs-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: Warnings in mingw64 builds on master


From: Óscar Fuentes
Subject: Re: Warnings in mingw64 builds on master
Date: Sun, 16 Aug 2020 18:45:31 +0200
User-agent: Gnus/5.13 (Gnus v5.13) Emacs/27.0.91 (gnu/linux)

Eli Zaretskii <eliz@gnu.org> writes:

>> >> if none of those conditions are true
>> >
>> > That cannot happen.
>> 
>> True, but it requires deeper analysis for the compiler to prove it.
>
> You mean, pay attention to the test of the same flags a few lines
> before?

The information gained about the contents of fd_info[fd] from that test
is discarded when the compiler finds a call to an external function
(DebPrint) a few lines below, since DebPrint (or one of the functions it
calls) might change the contents of the global fd_info array.

If the OP was not building with EMACSDEBUG defined, the warning would be
bogus indeed, since DebPrint is a no-op on that case. But please note
that the warning says "may be undefined", that is, the compiler is just
saying that it was unable to prove that `rc' is assigned before it is
used. It is not a bug, but a limitation, a QoI issue.

This piked my curiosity and wrote this sample:

#include <stdlib.h>

enum { FILE_PIPE, FILE_SERIAL, FILE_SOCKET, FILE_READ, FILE_CONNECT};

typedef struct
{
  unsigned         flags;
} filedesc;

extern filedesc fd_info [10];

extern void _DebPrint (const char *fmt, ...);
#define DebPrint(stuff) _DebPrint stuff
// #define DebPrint(stuff) ((void) 0)

int _sys_read_ahead (int fd) {
  int rc;

  if ((fd_info[fd].flags & (FILE_PIPE | FILE_SERIAL | FILE_SOCKET)) == 0
      || (fd_info[fd].flags & FILE_READ) == 0)
  {
    DebPrint (("_sys_read_ahead: internal error: fd %d is not a pipe, serial 
port, or socket!\n", fd));
    return(0);
  }

  if ((fd_info[fd].flags & FILE_CONNECT) != 0)
    DebPrint (("_sys_read_ahead: read requested from fd %d, which waits for 
async connect!\n", fd));

  if (fd_info[fd].flags & FILE_PIPE) {
    rc = 1;
  }
  else if (fd_info[fd].flags & FILE_SERIAL) {
    rc = 2;
  }
  else if (fd_info[fd].flags & FILE_SOCKET) {
    rc = 3;
  }

  return rc;
}


which compiled with `gcc -c -Wall -Wmaybe-uninitialized' (gcc 10.1)
shows no warnings, which indeed might indicate a bug. OTOH, `clang -c
-Wall' (clang 11) shows:


w32.c:35:12: warning: variable 'rc' is used uninitialized whenever 'if' 
condition is false [-Wsometimes-uninitialized]
  else if (fd_info[fd].flags & FILE_SOCKET) {
           ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
w32.c:39:10: note: uninitialized use occurs here
  return rc;
         ^~
w32.c:35:8: note: remove the 'if' if its condition is always true
  else if (fd_info[fd].flags & FILE_SOCKET) {
       ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
w32.c:17:9: note: initialize the variable 'rc' to silence this warning
  int rc;
        ^
         = 0
1 warning generated.


which is quite illustrative. But if you change the definition of
DebPrint to the no-op version, it keeps showing the same warning, which
demontrates the limitations of the compiler.

Right now the point of this type of warnings is that *sometimes* they
are helpful. The compiler guys try to do their best, but the result
never will be perfect, it can't be.




reply via email to

[Prev in Thread] Current Thread [Next in Thread]